33

我有一个看起来像这样的课程:

class Foo
{
public:
    Foo();
    virtual ~Foo();

private:
    Odp* bar;
};

我希望初始化barNULL. 这是最好的方法吗?

Foo::Foo() : bar(NULL)
{
}

另外,析构函数是否必须是虚拟的?(如果这是真的,那么构造函数也必须是虚拟的吗?)

4

7 回答 7

40

我希望初始化barNULL. 这是最好的方法吗?

这是正确的方法。所以,是的。

另外,析构函数是否必须是虚拟的?

不。只有当你从类继承时析构函数才需要是虚拟的,Foo并且将使用Foo指针来删除那些派生类(尽管作为一般经验法则,如果有任何其他虚拟成员,它应该是虚拟的)。

(如果这是真的,那么构造函数也必须是虚拟的吗?)

不,构造函数既不需要virtual不能

于 2010-07-07T17:53:06.620 回答
10

存在四种不同的方式。哪一个是最好的取决于你

Foo::Foo() : bar() // value initialization
{
}

Foo::Foo() : bar(0) // direct null pointer constant
{
}

Foo::Foo() : bar(NULL) // null pointer constant by macro
{
}

Foo::Foo() : bar(nullptr) // pointer literal of type std::nullptr_t
{
}
于 2010-07-07T18:06:38.143 回答
10
  1. 是的,初始化列表是最好的。

  2. 也许。如果您打算在类中拥有任何其他虚拟函数,或者如果您打算从该类继承(尽管通常这些东西一起使用),则析构函数应该是虚拟的。

  3. 不,在 C++ 中不可能有虚拟构造函数。(这样的事情甚至意味着什么?)

您的问题的性质向我表明您并不真正了解virtual关键字的作用或用途,您只是在复制您在其他地方或教程中看到的内容。最好了解您正在编写的所有代码的目的。这里可能是一个开始的地方:http: //www.parashift.com/c++-faq-lite/virtual-functions.html

于 2010-07-07T17:52:46.010 回答
4
  1. 是的
  2. 关于你关于析构函数是虚拟的第二个问题,请参阅: http: //www.parashift.com/c++-faq-lite/virtual-functions.html#faq-20.7 简短的回答,在你的情况下,没有析构函数不是必要的.
  3. 没有虚拟构造函数之类的东西。
于 2010-07-07T17:55:01.497 回答
3

您可能要考虑的另一个选项是使用智能指针类(例如boost::scoped_ptr,boost::shared_ptr或 C++0x's unique_ptr)而不是原始指针。如果您不需要其他显式初始化,智能指针的构造函数将确保将其初始化为类似 NULL 的内容。智能指针还将确保指向的对象被销毁。

您只需要确定适合该项目的智能点策略并相应地选择(auto_ptr只要您了解各种陷阱,甚至可能比原始指针更好)。

于 2010-07-07T18:03:39.930 回答
2

1,是的

2,仅当您希望某人能够从您的类派生并使用指向基类的指针时-但无论如何都要使 dtor 虚拟

3,不,你不能有一个虚拟的ctor(或者我想所有的ctor都是虚拟的?)

于 2010-07-07T17:52:50.253 回答
0

虚函数用于确定在运行时必须调用类的哪个函数(在基类和派生类中都定义)。但是当创建对象时,编译器知道要调用哪个构造函数。例如。当创建基对象时,基构造函数被调用,派生类也是如此。因此,将构造函数设为虚拟没有任何意义。但是一旦基类对象指针指向派生类对象,然后调用析构函数,编译器就会混淆需要调用哪个析构函数(基类或派生类),即只能使用查找表 vtable 解决,因此析构函数需要是虚拟的。

于 2014-07-29T14:35:03.280 回答