0

I'm in doubt on how to make object initialization without a default constructor on the superclass.

#include <iostream>

class A
{
protected:  
    A(std::string title, int xpos, int ypos);
};

class B : A
{
protected:
    //Is that correct?
    A* m_pA(std::string title, int xpos, int ypos); 
    //Why not just A* m_pA;? 
public:
    B(std::string title, int xpos, int ypos);
};

B::B(std::string title, int xpos, int ypos) : m_pA(title, xpos, ypos)
{
    //does nothing yet.     
}

As you can see I'm trying to initialize the m_pA object of type A in the constructor of B, the VC is throwing me:

"m_pA" is not a nonstatic data member or base class of class "B"

You can see the example compiled and the errors here.

I want to know why and how initialize a member object of a class without the default constructor, and why I am wrong.

Thanks in advance!

ranu
  • 622
  • 15
  • 25
  • 1
    do you really mean to inherit from A, and have a member pointer to A? anyway, the protected declaration is a method. you still have to initialize the base – sp2danny Jul 08 '14 at 02:00
  • `A* m_pA(std::string title, int xpos, int ypos);` is a function in class B returning a pointer to A. – drescherjm Jul 08 '14 at 02:00
  • yea @sp2danny you may be right, my head, is just so confused. D: Anyway, if I want a object of type A, how can I initialize it? I just want to call B and the A will be initialized, that's the objective, the ask may be unclear... And drescherjm you are right! – ranu Jul 08 '14 at 02:03
  • And because, as already said `m_pA` is not a non-static member object, trying to initialize it in the ctor init list is an error. Anyway, you want to pass the parameters to the `A` base-class sub-object there.... (replace `m_pA` with `A` in the list) – Deduplicator Jul 08 '14 at 02:04
  • Get rid of m_pA completely. Change the constructor to `B::B(std::string title, int xpos, int ypos) : A(title, xpos, ypos) {}` – drescherjm Jul 08 '14 at 02:04
  • @Deduplicator yes, that is what I want to do, pass the arguments to the constructor of A(the base-class), can you give me an idea on how to do that? – ranu Jul 08 '14 at 02:05
  • Uow, @drescherjm gave the answer, how about write an answer drescherjm? I'll mark it as right. – ranu Jul 08 '14 at 02:06
  • It's a duplicate (who'd have thought), so no need. Unless someone can write a better answer than found there? – Deduplicator Jul 08 '14 at 02:09
  • I got beat on that before I could finish typing.. Also I was pretty sure it was a duplicate. – drescherjm Jul 08 '14 at 02:09

3 Answers3

1

You need to explicitly initialize the base class when you construct the subclass.

B(std::string title, int xpos, int ypos)
    : A(title, xpos, ypos)
{}

You should probably also pass those string by const reference, otherwise you're making a heap of unecessary copies.

Aesthete
  • 18,622
  • 6
  • 36
  • 45
1

Your code has a few errors. First, for an inherited class to access protected variables/functions, the inherited class must be friended. Second, your private variable m_pA is a pointer. You cannot initialize a pointer to A the same way you would an instance of A. Take a look at this code:

#include <iostream>

class A
{
    friend class B;
protected:  
    A();
    A(std::string title, int xpos, int ypos);
};

A::A()
{
//Do something
}
A::A(std::string title, int xpos, int ypos)
{
//Do something
}

class B : A
{
protected:
    A* m_pA;    
public:
    B(std::string title, int xpos, int ypos);
};

B::B(std::string title, int xpos, int ypos)
{
    m_pA = new A(title, xpos, ypos);
}

int main() {

    return 0;
}

You can verify here: http://ideone.com/gL1OxH

tpdietz
  • 1,358
  • 9
  • 17
  • Your answer provides me a flexible initialization of m_pA, that's what I need, I tried to do exactly what you've done, but without the friend class B, I didn't knew about: `for an inherited class to access protected variables/functions, the inherited class must be friended`. – ranu Jul 08 '14 at 02:38
  • Glad I code help. You can also try to remove "friend class B", and change the class declaration of B to: 'class B : protected A', always more than one way to skin a cat. – tpdietz Jul 08 '14 at 02:41
0
class B : A
{
protected:
    A* p;
    A a;
public:
    B(std::string title, int xpos, int ypos)
         : A(title, xpos, ypos)          // init base
         , p(new A(title, xpos, ypos))   // init pointer
         , a(title, xpos, ypos)          // init member
    {}
};
sp2danny
  • 7,488
  • 3
  • 31
  • 53
  • In particular, the constructor initializes the data members before calling the base class constructor. And more broadly, the OP's problem was, he thought he had to provide a data member for a base class, when it's really implicit in the derived class. – NicholasM Jul 08 '14 at 02:12
  • @NicholasM: It doesn't. Construction order per standard: Virtual Bases, Other Bases, Members, in reading order of their definition, not of the init list. – Deduplicator Jul 08 '14 at 02:15
  • it was intended to show use cases of all the things he might want – sp2danny Jul 08 '14 at 02:17
  • @drescherjm: Please elaborate, what is wrong? – Deduplicator Jul 08 '14 at 02:20
  • I retract my comment. Must read answers more clearly especially while watching sports.. – drescherjm Jul 08 '14 at 02:38