:
class Foo
{
public:
Foo();
virtual ~Foo();
private:
Odp* bar;
};
我希望将 bar
初始化为 NULL
。这是最佳方式吗?
Foo::Foo() : bar(NULL)
{
}
还有,析构函数必须是虚函数吗?(如果是这样的话,那构造函数也必须是虚函数吗?)
:
class Foo
{
public:
Foo();
virtual ~Foo();
private:
Odp* bar;
};
我希望将 bar
初始化为 NULL
。这是最佳方式吗?
Foo::Foo() : bar(NULL)
{
}
还有,析构函数必须是虚函数吗?(如果是这样的话,那构造函数也必须是虚函数吗?)
我希望将
bar
初始化为NULL
,这是最好的方法吗?
这是正确的方法,所以是的。
另外,析构函数是否必须是虚拟的?
不是必须的。只有当您从Foo
类继承并将使用Foo
指针删除这些派生类时(尽管作为一般准则,如果有其他虚成员,则应该是虚拟的)才需要将析构函数设置为虚拟的。
(如果是这样,那么构造函数也必须是虚拟的吗?)
不需要。构造函数既不需要也不能是虚拟的。
m_non_const_var
应该在初始化列表中初始化。当你写=OTHER_VALUE
时,你是在赋值而不是初始化。初始化列表是用来初始化的。 :) 如果你的代码只是不一致,或者有某些原因不能初始化,那么它会让我感到困惑。构造函数体应该是运行任何需要初始化类的代码而不是成员变量的地方。 - GManNickG是的,初始化列表是最佳选择。
也许。如果你打算在类中有任何其他虚函数,或者打算从该类进行继承(尽管通常这些事情是一起完成的),那么析构函数应该是虚拟的。
不可以。在C++中不可能有虚拟构造函数。(这样的东西究竟意味着什么?)
你提出的问题的性质使我认为你并不真正理解virtual
关键字的作用及其用途,而只是复制了某个地方或教程上的内容。最好理解你正在编写的代码的所有目的。以下可能是一个开始的地方:http://www.parashift.com/c++-faq-lite/virtual-functions.html
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
{
}
Foo::Foo(): bar(nullptr){}
。 - nurettinboost::scoped_ptr
,boost::shared_ptr
或C++0x的unique_ptr
),而不是原始指针。智能指针的构造函数将确保它被初始化为类似于NULL的东西,如果你不需要其他显式初始化。智能指针还将确保所指向的对象被销毁。auto_ptr
可能比原始指针更好,只要你意识到各种陷阱)。1,是的。
2,只有当你希望某人能够从你的类派生并使用指向基类的指针时才需要这样做 - 但无论如何都要使dtor虚拟化。
3,不,你不能拥有虚拟构造函数(或者我想说所有构造函数都是虚拟的吧?)
虚函数用于在运行时确定类(在基类和派生类中都定义)的哪个函数必须被调用。但是当对象被创建时,编译器知道应该调用哪个构造函数。例如,当创建基类对象时,将调用基类构造函数,创建派生类对象时也是如此。因此,使构造函数成为虚函数没有任何意义。但是,一旦基类对象指针指向派生类对象,然后调用析构函数,编译器会混淆需要调用哪个析构函数(基类或派生类),这只能通过查找表vtable来解决,因此析构函数需要是虚函数。
Foo::Foo() : bar() {}
(注意,没有NULL
)。最好的方式是不使用指针。 - GManNickGNULL
是隐式的吗? - Nick HeinerNULL
(它只是0
)。 “NULL
是隐式的吗?” 是的。bar()
是一个值初始化;对于指针,它将其初始化为 null。 - Mike Seymour