class myclass{
public: void hello(){
std::cout<<"Hello"<<"\n";
}
}
myclass* mc = new myclass;
mc->hello();
是否动态分配了函数hello
,还是没有动态分配?
答案 0 :(得分:3)
函数不是对象(至少在C ++中),并且没有生命周期。他们就在那里。永远和永远。 (再次,从C ++的角度来看。)
答案 1 :(得分:3)
功能不是&#34;已分配&#34;一点都不在引擎盖下,非虚拟功能对类没有固有的物理依附。成员函数只是一层薄薄的语法糖而不是普通的独立函数。例如,在您的情况下,成员函数hello
被转换为普通的独立函数
void myclass_hello(myclass *this) {
std::cout<<"Hello"<<"\n";
}
当你打电话
mc->hello();
编译器基本上用
替换此调用myclass_hello(mc);
在C ++的早期,当许多C ++编译器被实现为C编译器的前端时,这正是C ++成员函数被转换为C函数的方式。
在&#34;分配和#34;方面没有区别。成员函数和普通独立函数之间。无论您创建的该类型的对象有多少,它本身只存在一个成员函数实例。
使用虚函数时,事情会变得复杂一些,但仍然不会产生任何需要&#34;分配&#34;成员职能。每个版本的虚拟成员函数只有一个实例,它仍然独立于实际对象而存在。
答案 2 :(得分:1)
当你进入c ++的内部时,你会发现编译器会对代码执行各种疯狂的操作,例如完全更改函数的名称以支持函数重载。函数不是C ++中的对象,而是对函数表的引用。我想你想知道的是,如果你把一个方法放在一个类之外是更好的,因为对于每个类的实例都没有“副本”。事实是你没有得到函数的“副本”,但是获得指针变量的副本?答案是否定的,c ++将只分析代码,并在您使用它的任何地方放置单个函数调用。任何引用都会在将代码中的变量名转换为实际内存位置时考虑“this”或实例数据。
答案 3 :(得分:0)
涉及功能时没有内存分配。
这些只是您可执行文件中的一堆代码
答案 4 :(得分:0)
hello
的实际代码只有一个实例,它在可执行文件中/在程序运行时加载到内存中。类(对象)的所有实例都使用代码的一个实例。
答案 5 :(得分:0)
hello方法的机器代码是在编译时生成的。由于它不是虚方法,编译器可以确定如何直接调用它。等效代码可能是:
struct MyStruct {};
void hello(MyStruct* this)
{
std::cout << "Hello" << std::endl;
}
int main(int, char**)
{
MyStruct* ms = new MyStruct;
hello(ms);
return 0;
}
答案 6 :(得分:0)
这完全取决于背景,更确切地说取决于它是什么样的功能。 你永远不会分配一个函数,因为它的代码不是数据,唯一可以是动态的是每个类调用哪些函数,这些是虚函数。
这是一个普通的类成员函数:
void MyClass::CallFunction()
{
}
实际上编译器,只是C ++的许多编译器都这样做,添加一个通常“不可见”但同时可访问的函数参数,通常是列表中的第一个,类对象的内存指针,* this。 / p>
void MyClass::CallFunction(MyClass *this)
{
}
如果你声明了成员函数 static ,你基本上创建了一个在类范围内但不属于该类的函数,因此它没有这个指针。
由于作用域,编译器会自动引用您的类变量,因此您不必这样做,因此使用
访问属于该类对象的任何内容。this->classVariable = 0;
对于虚函数,编译器创建了一个由编译器处理的vtable,因此函数覆盖和多态实际上可以工作。 vtable只存储指向函数的指针,所以即使在这种情况下函数也是固定的。
由编译器决定在类对象中实际分配哪些部分,这些部分通常是非const非静态成员变量,因此您可以将实际对象视为存在于所有变量中的所有变量的简单结构。所有子类和主类。