-1

I've two classes called FWindow and FFramwWindow. The FFramwWindow class inherits the FWindow. The FWindow class contains two constructor method.

The first one is default constructor and the second one contains one parameter of int type.

I call the second constructor from the FFramwWindow class default constructor to initialize a member variable of the FWindow class called 'value'.

But I don't know why it isn't working -

class FWindow {
public:
    int value;
    FWindow() 
    {
        this->value = 0;
    }
    FWindow(int val) 
    {
        this->value = val;
    }
};

class FFramwWindow : public FWindow
{
public:
    FFramwWindow()
    {
        FWindow::FWindow(6);

        printf("value %d\n", this->value);
    }
};

int main(int argc, _TCHAR* argv[])
{
    FFramwWindow obj;

    return 0;
}

The above code prints - value 0

Where I expected it will print - value 6

Seems it's only calling the default base class constructor, not the second one that I called explicitly.

Note: I'm using Visual Studio 2008

Farhad Reza
  • 424
  • 4
  • 16
  • Possible duplicate of [call class constructor as a method](http://stackoverflow.com/questions/34110734/call-class-constructor-as-a-method) – user4581301 Dec 06 '15 at 17:11
  • Why down vote? I thought C++ will allow me to call base class constructor explicitly inside the derived class constructor body. I thought I can call class constructor in this way - 'FWindow::FWindow()' like we call base class destructor. For example - 'FWindow::~FWindow()'. If 'FWindow::FWindow()' creates a local object then will 'FWindow::~FWindow()' create a local object? – Farhad Reza Dec 07 '15 at 08:47

3 Answers3

8

Because you should do the following in constructor:

FFramwWindow() : FWindow(6)
{
....

In your original code you create a local (in constructor scope) object of FWindow.

Alex
  • 9,891
  • 11
  • 53
  • 87
  • Oh right, I still was trying to figure out if his call to the base constructor was valid inside the body... – elios264 Dec 06 '15 at 17:00
  • @alex The constructor call creates a local object of FWindow? Strange. I thought C++ would be more smart in that case. – Farhad Reza Dec 06 '15 at 17:08
  • 1
    @MohammadShuvo, compiler does what you say it to do. – Alex Dec 06 '15 at 17:09
  • 2
    @MohammadShuvo It is smarter than that. Member variables and Base Classes need to be initialized before you can use them in the body of a method. The object has to be ready to use before you use it. The member initializer list takes care of that problem. – user4581301 Dec 06 '15 at 17:13
  • @MohammadShuvo: You mean less flexible, by not allowed you to declare temporary objects! – Martin York Dec 06 '15 at 19:32
  • @LokiAstari: No, I thought C++ will allow me to call base class constructor explicitly inside the derived class constructor body. I thought I can call constructor in this way - 'FWindow::FWindow()' like we call base class destructor. For example - 'FWindow::~FWindow()'. – Farhad Reza Dec 06 '15 at 20:18
  • @MohammadShuvo Strongly recommend against directly calling the destructor; it will almost certainly end in results ranging from from bad idea to utter expletive deleted disaster. I'm sure there are cases where it is a viable option, and I'm also sure you can code through a lengthy career without finding such a case. Even less likely will you find a case where it is a good idea. Let the compiler take care of destruction when it passes out of scope or use `delete` if allocated with `new`. – user4581301 Dec 07 '15 at 19:52
2

the code

FWindow::FWindow(6);

is not a call to the parent constructor, but the creation of a local instance of FWindow. The correct syntax in C++ to specify which FWindow constructor should be called is

FFramwWindow() : FWindow(6)
{
    ...
}

If you do not specify the constructor to use for the base class (and for data members), C++ uses the default constructor, that is

FFramwWindow()
{
    ...
}

is equivalent to

FFramwWindow() : FWindow()
{
    ...
}

Note that if you have multiple inheritance you should constructors for each base class separating them with comma. As bonus information, the base constructors are called in the order specified in the inheritance definition, not those in which you specify them in the constructor:

class A {
    A();
    A(int n);
    A(string s);
};

class B {
    B(int n = 6);
}

class C {
    C();
    C(float x);
}

class D: public A, public B, public C {
    D();
}

D::D() : C(3),A(5)
{
}

In this example, creating an instance of D will invoke in order the constructors for A(5), B(6), C(3.0), D()

pqnet
  • 6,070
  • 1
  • 30
  • 51
  • In general, it's not quite equivalent. `FFramwWindow(): FWindow()` specifies that the `FWindow` will be *value-initalized*. Without this, it will be *default-initialized* if the `FFramwWindow` is being default-initialized. In this specific case it's moot because `FWindow` has a user-written constructor. – M.M Dec 06 '15 at 20:45
1

You must call the constructor function of the base class when you declare the derived class's constructor. Consider this example:

#include<iostream>
class base
{
public:
    int i;
    base()
    {
        i = 0;
    }
    base(int p)
    {
        i = p;
    }
};

class derived1: public base
{
public:
    derived1():base()
    {
        std::cout<<i<<std::endl; //i is 0 here
    }
};

class derived2: public base
{
public:
    derived2():base(10)
    {
        std::cout<<i<<std::endl; //i is 10 here
    }
};

class derived3: public base
{
public:
    derived3(int x):base(x)
    {
        std::cout<<i<<std::endl;
        //this takes an argument from the derived class's constructor
        //as base class's constructor's parameter
    }
};

int main()
{
    derived1 d1;
    derived2 d2;
    derived3 d3(9);
    return 0;
}

In derived1 class, the first constructor of the base class is called. In derived2 class, the second constructor is called. And in third case, the constructor function takes an argument which is passed to the base class's constructor (That means we are using the second constructor of base class).

In your code,You didn't call the base class's constructor which by default calls the constructor that takes no argument. That's why it is outputting 0.

FWindow::FWindow(6);

This statement just creates a temporary new object of class FWindow which is destroyed right after this statement is executed. Constructor functions are meant to be called automatically when you create a object. They are not meant to be called manually.

You can find some explanation here: http://www.geeksforgeeks.org/possible-call-constructor-destructor-explicitly/

Hridoy
  • 63
  • 7