Problem with hierachy and constructor

N

Nafai

Hello. I want to do something like this:

class A { // It's virtual
protected:
float* data;
int n;
public:
A(int a);
virtual float* createData();
//...
};

class B : public A {
public:
float* createData();
};

A::A(int a)
{
n=a;
data=createData();
}

float* B::createData()
{ // ... // }

That is, to construct a derived class of A, I only need to define
createData. But I get compiling errors. What's the problem?
 
B

Bob Hairgrove

Hello. I want to do something like this:

class A { // It's virtual
protected:
float* data;
int n;
public:
A(int a);
virtual float* createData();
//...
};

It's not a good idea to have protected data members.
class B : public A {
public:
float* createData();
};

A::A(int a)
{
n=a;
data=createData();
}

float* B::createData()
{ // ... // }

That is, to construct a derived class of A, I only need to define
createData. But I get compiling errors. What's the problem?

You have no default constructor for the base class, so you must
initialize it in B's constructor ... which is also missing.

Also, the base class is created *before* the derived class, so you can
only call the base class implementation of createData() ... which I
don't see anywhere. As a rule, never call any virtual functions in the
constructors of either the base or the derived class, nor in their
destructors.

A should also have a virtual destructor.
 
J

JKop

Bob Hairgrove posted:
It's not a good idea to have protected data members.


I'm sure they'd come in handy somewhere, just like how you can explicitly
call an object's destructor.

You have no default constructor for the base class, so you must
initialize it in B's constructor ... which is also missing.

Also, the base class is created *before* the derived class, so you can
only call the base class implementation of createData() ... which I
don't see anywhere. As a rule, never call any virtual functions in the
constructors of either the base or the derived class, nor in their
destructors.

A should also have a virtual destructor.


Only if B has defined a destructor, and if you think that it's likely that
an object of B would be destroyed via a pointer to A, as in:

A* blah = new B;

delete blah;


To define virtual destructors just under the premise that "I'm being
inherited from!" is damn right inefficient.

Although I would conceed that if one were writing reusable code, then
informative documentation would be in order:


/* NB: This class's destructor is not virtual */
class Blah
{
...


-JKop
 
C

Catalin Pitis

Nafai said:
Hello. I want to do something like this:

class A { // It's virtual
protected:
float* data;
int n;
public:
A(int a);
virtual float* createData();
//...
};

class B : public A {
public:
float* createData();
};

A::A(int a)
{
n=a;
data=createData();
}

float* B::createData()
{ // ... // }

That is, to construct a derived class of A, I only need to define
createData. But I get compiling errors. What's the problem?

There are several rules related to constructors.

First part of the problem:
A default constructor is generated by the compiler for any class that has no
constructor declared. If you declare a constructor of the class (see A( int
a)), there will be no default constructor generated anymore. If you need the
default constructor you should declare and implement it explicitly.

The second part of the problem:
In the derived class, if you don't call explicitly the base class'
constructor (like B(): A( 10) {} ) the compiler tries to generate code for
calling the default constructor of the base class. Since A has no default
constructor, the compiler fails and a compiler error is generated.

The third part of the problem:
B has no constructor declared, so a default constructor is generated by the
compiler (see First part of the problem). That generated default constructor
calls the default constructor of the class A (see the second part of the
problem), which doesn't exist (see First part of the problem :), so a
compiler error is generated.

The conclusion:

Define the default constructor for B and call the constructor of A.
Something like this:

B::B(): A( 0) { }

Br/
Catalin
 
R

Richard Herring

Nafai said:
Hello. I want to do something like this:

class A { // It's virtual
protected:
float* data;
int n;

That looks like rolling your own std::vector<float> to me.
Why not use a real one?
 
R

Richard Herring

[...]
A should also have a virtual destructor.

Only if B has defined a destructor,[/QUOTE]

It has, whether you can see it or not.
and if you think that it's likely that
an object of B would be destroyed via a pointer to A, as in:

A* blah = new B;

delete blah;

Well, given the presence of a virtual function, that's a pretty good
bet.
To define virtual destructors just under the premise that "I'm being
inherited from!" is damn right
downright?

inefficient.
You do know what is the root of all evil?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top