在构造函数中调用类的函数。 C ++

时间:2011-10-18 14:52:12

标签: c++

我很好奇,因为我认为这个想法是一个解决方案,可以提高我的代码的可读性。当我创建一个类的对象时,有没有办法在构造函数中调用一个对象/类的函数?如果我不能清楚地解释自己,那就问问我会尝试解释它。

7 个答案:

答案 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或B的基类中定义

对于当前代码,正确的方法是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)之外,你应该在调用函数时检查它们,无论你在哪里调用它们。