2

I encounter some strange things in C++, but I don't know why?

I have a class like this

header file

class foo
{
public:
    void call_foo();

    int get_foo();

    int get_foo(int val);
};

here is the cpp file

#include "foo.h"
#include <iostream>

using namespace std;

void foo::call_foo()
{
    int i = 0;
    int j = 33;
    cout << i + j << endl;
    cout << "Hello, Foo" << endl;
}

int foo::get_foo(int val)
{
    int a = 345;
    int rc = val + a;
    cout << rc << endl;
    return rc;
}

int foo::get_foo()
{
    int a = 100;
    int d = 23;
    int rc = a + d;

    cout << rc << endl;
    return rc;
}

I using code to test as below

int main()
{
    int* val = new int[100];

    foo* foo_ptr;
    foo_ptr = (foo*)val;
    foo_ptr->call_foo();
    foo_ptr->get_foo();
    foo_ptr->get_foo(100);

    delete [] val;
    return 0;
}

then i compile and execute it.

clang++ foo.cpp main.cpp

Apple LLVM version 5.0 (clang-500.2.79) os x 10.9

an int pointer convert to an object pointer, then call it's methods, it work! so weird! Is there anybody know what is going on?

I wrote an article on my blog about why it works in my understood, Thanks all of you!! about object structure, virtual function table. just Chinese version :)

4

4 回答 4

2

您所经历的称为未定义行为。

未定义的行为意味着“任何事情都可能发生”。 此处的任何内容都包括您的代码有效、做了您期望它做的事情或没有做您期望它做的事情的错觉——比如崩溃。

引发未定义行为的代码始终是错误代码。你不能依赖未定义的行为,如果仅仅是因为你无法预测会发生什么。

现在在这种情况下,调用这些方法可能会起作用的原因是,在实践中,一个类的实例并没有得到它自己的每个非static方法的代码副本。相反,在所有foo. 指向该代码的指针永远不会改变,因此当您(错误地)解析一个指针foo,然后通过该指针调用其中一个方法时,实际上调用了您期望调用的实际方法。然而,这仍然是未定义的行为,您需要修复您的代码。

于 2013-10-30T16:39:47.393 回答
1

这是未定义的行为,您的程序格式不正确。就语言规范而言,任何事情都可能发生。

它恰好看起来起作用,因为没有成员函数访问属于特定foo对象实例的任何数据。他们所做的只是分配本地数据和访问权限cout

于 2013-10-30T16:38:44.323 回答
0

它不起作用,它具有未定义的行为。

但是,这些函数不是虚拟的,并且该对象没有数据成员,因此您的程序很可能实际上不会触及无效内存,因此与在有效对象上调用函数具有相同的效果。

于 2013-10-30T16:38:46.693 回答
0

您的类没有成员也没有虚函数,因此当您通过任意指针调用成员函数时,它将“工作”,因为您有一个静态绑定的函数调用,并且不会进行任何无效的内存访问。如果您尝试调用虚函数或访问成员变量,就会发生不好的事情。

于 2013-10-30T16:41:44.270 回答