我很好奇,因为我认为这个想法是一个解决方案,可以提高我的代码的可读性。当我创建一个类的对象时,有没有办法在构造函数中调用一个对象/类的函数?如果我不能清楚地解释自己,那就问问我会尝试解释它。
答案 0 :(得分:8)
当然可以......
但是只有一个问题:避免调用虚方法,因为你不会调用派生最多的方法,只能为该类派生最多的方法。例如:
class A
{
public:
A() { std::cout << "A::A()" << std::endl ; }
virtual void foo() { std::cout << "A::foo()" << std::endl ; }
} ;
class B : public A
{
public:
B() { std::cout << "B::B()" << std::endl ; this->foo() ; }
virtual void foo() { std::cout << "B::foo()" << std::endl ; }
} ;
class C : public B
{
public:
C() { std::cout << "C::C()" << std::endl ; }
virtual void foo() { std::cout << "C::foo()" << std::endl ; }
} ;
int main(int argc, char * argv[])
{
C c ;
return 0 ;
}
输出将是:
A::A()
B::B()
B::foo()
C::C()
创建C
对象时,构造函数将被链接:首先A()
,然后是B()
,然后是C()
。正如我们通过阅读代码所知,B()
构造函数调用foo()
,这是一个虚方法。
在C ++中,B()
调用的方法将是foo()
方法:
对于当前代码,正确的方法是B::foo()
。
当您执行C对象的B构造函数时,只构造了C的A和B部分。 C部分尚未构建,因此尝试从B的构造函数访问C的数据可能会使代码崩溃,并且无论如何都是语义错误。
所以我们必须避免这种情况。从B的一种方法访问C数据的唯一正常方法是使用被C覆盖的虚拟方法。
因此,为避免这种情况,虚构方法在构造函数和析构函数中没有“完全解析”(由于相同的潜在原因,它们会遇到同样的问题)。
请注意,此C ++行为与Java和C#不同。
答案 1 :(得分:5)
是的,你可以,只要它不是虚函数。从构造函数调用虚函数通常不会按预期执行,并且可能会调用未定义的行为,因为对象(尤其是派生类)可能无法完全初始化。
答案 2 :(得分:2)
在构造函数中调用函数没问题。在构造函数中调用在派生类中重写的虚函数可能是C ++中的一个问题,但这可能不是您想要的。
答案 3 :(得分:2)
从构造函数中调用另一个成员函数没有任何问题,只需确保首先正确初始化该对象,以便该函数不会失败。
将初始化分解为可以从构造函数外部调用的公共函数非常方便。
答案 4 :(得分:1)
您可以从类ctor中调用任何非虚拟成员函数,没有任何问题。避免虚拟呼叫,因为它们可能无法按照您的预期进行操作。
struct foo {
foo() {
call_me();
}
void call_me() {
std::cout << "something" << std::endl;
}
};
答案 5 :(得分:0)
是的,这完全没问题。只需像在其他任何地方一样调用该函数。
答案 6 :(得分:0)
这里没有问题,这很好。这当然是假设一些事情:
定义了该功能。 初始化函数正在使用的变量,对象等。 该功能不是虚拟的。
当然,除了最后一个例外(haaahhhh)之外,你应该在调用函数时检查它们,无论你在哪里调用它们。