views:

271

answers:

7

I have a class that looks like:

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

private:
    Odp* bar;
};

I wish to initialize bar to NULL. Is this the best way to do it?

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

Also, is it necessary that the destructor is virtual? (If that is true, then must the constructor be virtual as well?)

+9  A: 
  1. Yes, the initializer list is best.

  2. Maybe. The destructor should be virtual if you intend to have any other virtual functions in the class, or if you intend the class to be inherited from (although usually those things go together).

  3. No. It's not possible to have a virtual constructor in C++. (what would such a thing even mean?)

The nature of your question suggests to me that you don't really understand what the virtual keyword does, or what is is for, and you are just copying something you saw elsewhere or in a tutorial. It's best to understand the purpose of all of the code you're writing. Here might be a place to start: http://www.parashift.com/c++-faq-lite/virtual-functions.html

Tyler McHenry
Just an FYI in response to "what would such a thing even mean?": some people might use the term "virtual constructor" for the factory pattern (http://www2.research.att.com/~bs/bs_faq2.html#virtual-ctor).
Michael Burr
+1 for the link. It's pretty helpful.
Rosarch
+2  A: 

1, yes

2, only if you want somebody to be able to derive from your class and use a pointer to the base class - but make the dtor virtual anyway

3, no you can't have a virtual ctor (or all ctors are virtual I suppose?)

Martin Beckett
"all ctors are virtual" - no, the decision on which constructor to call is made at compile time. "Virtual" would imply a run-time decision.
Mike Seymour
+16  A: 

I wish to initialize bar to NULL. Is this the best way to do it?

It is the correct way. So, yes.

Also, is it necessary that the destructor is virtual?

No. The destructor only needs to be virtual if you will be inheriting from the Foo class and will be using a Foo pointer to delete those derived classes (although as a general rule of thumb, it should be virtual if there are any other virtual members).

(If that is true, then must the constructor be virtual as well?)

No. Constructors neither need to be virtual, nor can they.

greyfade
+1 Good concise answer. I initialize non-constant members in the ctor's body. It makes reading the code a bit more clear (in regard to the type of the member qualifier).
Poni
@Poni: No you don't, you reassign them. All members are initialized by the beginning of the constructor body. This is why it's generally seen as bad practice to "initialize" things there. Sure, with primitive types you lose nothing, but not all types are primitive, and it's best to be consistent. "Clear" will come as you use them more and get used to the syntax.
GMan
MyClass::MyClass() : m_const_var(VALUE) { this->m_non_const_var = OTHER_VALUE } <<<< didn't exactly get what you said GMan but this is what I meant to. So, you're saying this way is wrong? You're saying that we should include m_non_const_var's initialization in the ctor's members' initialization area just like the doing with m_const_var?
Poni
@Poni: I got that's what you said, I'm trying to point out that `m_non_const_var` should have been initialized in the initialization list. When you say `= OTHER_VALUE`, you are assigning, not initializing. Initialization list is for initializing. :) Your code would make me wonder if you were just being inconsistent or if there was some reason those couldn't be initialized. The constructor body should be where you run any code required to initialize your *class*, not the members.
GMan
Ahh, got your point. +1 from me as well!
Poni
The destructor only needs to be virtual if you want polymorphic deletion through a pointer to the base, otherwise make it protected and nonvirtual. See e.g. [Virtuality](http://www.gotw.ca/publications/mill18.htm).
Georg Fritzsche
@Georg Fritzsche: You're right. I've edited my answer.
greyfade
+4  A: 
  1. Yes
  2. Regarding your second question about destructor being virtual see: http://www.parashift.com/c++-faq-lite/virtual-functions.html#faq-20.7 Short answer, No destructor isn't necessary to be vitual in your case.
  3. There are no such things as virtual constructors.
bits
+3  A: 

Another option you might want to consider is to use a smart pointer class (such as boost::scoped_ptr, boost::shared_ptr or C++0x's unique_ptr) instead of a raw pointer. The constructor of the smart pointer will make sure it's initialized to something NULL-like if you don't need some other explicit initialization. The smart pointer will also ensure that the pointed-to object is destroyed.

You just need to decide what kind of smart point policy is appropriate for the item and choose accordingly (even auto_ptr might be better than a raw pointer as long as you're aware of the various pitfalls).

Michael Burr
+4  A: 

Three distinct ways exist. Which one is the best is up to you

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

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

Foo:Foo() : bar(NULL) // null pointer constant by macro
{
}
Johannes Schaub - litb
A: 

No. The destructor only needs to be virtual if you will be inheriting from the Foo class and will be using a Foo pointer to refer to those derived classes.

Slightly fewer cases actually, you only need it to be virtual if: - somebody inherits from your class - somebody else uses a pointer to your class to delete that object

And even then it would only cause problems if that derived class had a non-trivial destructor. Because that last one is very hard to determine the general idea is that if somebody derives from you, you should use a virtual destructor. Derives in this context is the Java "extends", not "implements".

dascandy