Top constructor Questions

List of Tags

Someone posted in a comment to another question about the meaning of the explicit keyword in C++. So, what does it mean?

Answered By: Skizz ( 452)

In C++, the compiler is allowed to make one implict conversion to resolve the parameters to a function. What this means is that the compiler can use single parameter constructors to convert from one type to another in order to get the right type for a parameter. Here's an example class with a constructor that can be used for implicit conversions:

class Foo
{
public:
  // single parameter constructor, can be used as an implicit conversion
  Foo (int foo) : m_foo (foo) 
  {
  }

  int GetFoo () { return m_foo; }

private:
  int m_foo;
};

Here's a simple function that takes a Foo object:

void DoBar (Foo foo)
{
  int i = foo.GetFoo ();
}

and here's where the DoBar function is called.

int main ()
{
  DoBar (42);
}

The parameter is not a Foo object. It is an int, though; and there exists a constructor for Foo that takes an int so that constructor can be used to convert the parameter to the correct type.

The compiler is allowed to do this once for each parameter.

Prefixing the explicit keyword to the constructor prevents the compiler from using that constructor for implicit conversions. Adding it to the above class will create a compiler error at the function call DoBar (42).

The reason you might want to do this is to avoid accidental construction that can hide bugs. Contrived example:

  • You have a MyString(int size) class with a constructor that constructs a string of the given size. You have a function print(MyString &), and you call it with print(3). You expect it to print "3", but it prints an empty string of length 3 instead.

I'm getting a warning from ReSharper about a call to a virtual member from my objects constructor. Why would this be something not to do?

Answered By: Greg Beech ( 343)

(Assuming you're writing in C# here)

When an object written in C# is constructed, what happens is that the initializers run in order from the most derived class to the base class, and then constructors run in order from the base class to the most derived class (see Eric Lippert's blog for details as to why this is).

Also in .NET objects do not change type as they are constructed, but start out as the most derived type, with the method table being for the most derived type. This means that virtual method calls always run on the most derived type.

When you combine these two facts you are left with the problem that if you make a virtual method call in a constructor, and it is not the most derived type in its inheritance hierarchy, that it will be called on a class whose constructor has not been run, and therefore may not be in a suitable state to have that method called.

This problem is, of course, mitigated if you mark your class as sealed to ensure that it is the most derived type in the inheritance hierarchy - in which case it is perfectly safe to call the virtual method.

If 'Test' is an ordinary class, is there any difference between:

Test* test = new Test;
//and
Test* test = new Test();
Answered By: Michael Burr ( 353)

Let's get pedantic, because there are differences that can actually affect your code's behavior. Much of the following is taken from comments made to an "Old New Thing" article.

Sometimes the memory returned by the new operator will be initialized, and sometimes it won't depending on whether the type you're newing up is a POD (plain old data), or if it's a class that contains POD members and is using a compiler-generated default constructor.

  • In C++1998 there are 2 types of initialization: zero and default
  • In C++2003 a 3rd type of initialization, value initialization was added.

Assume:

struct A { int m; }; // POD
struct B { ~B(); int m; }; // non-POD, compiler generated default ctor
struct C { C() : m() {}; ~C(); int m; }; // non-POD, default-initialising m

In a C++98 compiler, the following should occur:

  • new A - indeterminate value
  • new A() - zero-initialize

  • new B - default construct (B::m is uninitialized)

  • new B() - default construct (B::m is uninitialized)

  • new C - default construct (C::m is zero-initialized)

  • new C() - default construct (C::m is zero-initialized)

In a C++03 conformant compiler, things should work like so:

  • new A - indeterminate value
  • new A() - value-initialize A, which is zero-initialization since it's a POD.

  • new B - default-initializes (leaves B::m uninitialized)

  • new B() - value-initializes B which zero-initializes all fields since its default ctor is compiler generated as opposed to user-defined.

  • new C - default-initializes C, which calls the default ctor.

  • new C() - value-initializes C, which calls the default ctor.

So in all versions of C++ there's a difference between "new A" and "new A()" because A is a POD.

And there's a difference in behavior between C++98 and C++03 for the case "new B()".

This is one of the dusty corners of C++ that can drive you crazy. When constructing an object, sometimes you want/need the parens, sometimes you absolutely cannot have them, and sometimes it doesn't matter.

237
lomaxx

If I inherit from a base class and want to pass something from the constructor of the inherited class to the constructor of the base class, how do I do that?

For example,

If I inherit from the Exception class I want to do something like this:

class MyExceptionClass : Exception
{
     public MyExceptionClass(string message, string extraInfo)
     {
         //This is where it's all falling apart
         base(message);
     }
}

Basically what I want is to be able to pass the string message to the base Exception class

Answered By: Jon Limjap ( 298)

Modify your constructor to the following so that it calls the base class constructor properly:

public class MyExceptionClass : Exception
{
    public MyExceptionClass(string message, string extrainfo) : base(message)
    {
        //other stuff here
    }
}

Note that a constructor is not something that you can call anytime within a method. That's the reason you're getting errors in your call in the constructor body.

234
cod3-monk-3y

Is it possible to call a constructor from another (within the same class, not from a subclass)? If yes how? And what could be the best way to call another constructor (if there are several ways to do it)?

Answered By: Jon Skeet ( 340)

Yes, it is possible:

public class Foo
{
    private int x;

    public Foo()
    {
        this(1);
    }

    public Foo(int x)
    {
        this.x = x;
    }
}

To chain to a particular superclass constructor instead of one in the same class, use super instead of this. Note that you can only chain to one constructor, and it has to be the first statement in your constructor body.

EDIT: See also this related question, which is about C# but where the same principles apply.

173
Stormenet

As an c# developer I'm used to run through constructors:

class Test {
    public Test() {
        DoSomething();
    }

    public Test(int count) : this() {
        DoSomethingWithCount(count);
    }

    public Test(int count, string name) : this(count) {
        DoSomethingWithName(name);
    }
}

Is there a way to do this in c++ ?

I tried calling the Class name and using the 'this' keyword, but both fails.

Answered By: JohnIdol ( 241)

Unfortunately there's no way to do this in C++ (it's possible in C++11 though - see update at the bottom).

two ways of simulating this:

1) You can combine two (or more) constructors via default parameters:

class Foo {
 public:
   Foo(char x, int y=0);  // combines two constructors (char) and (char, int)
   ...
 };

2) Use an init method to share common code

class Foo {
 public:
   Foo(char x);
   Foo(char x, int y);
   ...
 private:
   void init(char x, int y);
 };

 Foo::Foo(char x)
 {
   init(x, int(x) + 7);
   ...
 }

 Foo::Foo(char x, int y)
 {
   init(x, y);
   ...
 }

 void Foo::init(char x, int y)
 {
   ...
 }

see this link for reference.

Update: Google rates this question high, so I think it's necessary to update it with current information. C++11 has been finalized, and it has this same feature (called delegating constructors).

The syntax is slightly different from C#:

class Foo {
public: 
  Foo(char x, int y) {}
  Foo(int y) : Foo('a', y) {}
};
151
Boris Callens

It's weird that this is the first time I've bumped into this problem, but:

How do you define a constructor in a C# interface?

Edit
Some people wanted an example (it's a free time project, so yes, it's a game)

IDrawable
+Update
+Draw

To be able to Update (check for edge of screen etc) and draw itself it will always need a GraphicsDeviceManager. So I want to make sure the object has a reference to it. This would belong in the constructor.

Now that I wrote this down I think what I'm implementing here is IObservable and the GraphicsDeviceManager should take the IDrawable... It seems either I don't get the XNA framework, or the framework is not thought out very well.

Edit
There seems to be some confusion about my definition of constructor in the context of an interface. An interface can indeed not be instantiated so doesn't need a constructor. What I wanted to define was a signature to a constructor. Exactly like an interface can define a signature of a certain method, the interface could define the signature of a constructor.

Answered By: Jon Skeet ( 116)

You can't. It's occasionally a pain, but you wouldn't be able to call it using normal techniques anyway.

In a blog post I've suggested static interfaces which would only be usable in generic type constraints - but could be really handy, IMO.

One point about if you could define a constructor within an interface, you'd have trouble deriving classes:

public class Foo : IParameterlessConstructor
{
    public Foo() // As per the interface
    {
    }
}

public class Bar : Foo
{
    // Yikes! We now don't have a parameterless constructor...
    public Bar(int x)
    {
    }
}