views:

123

answers:

6

Hello, trying to work out how to use constructors with an inherited class. I know this is very much wrong, I've been writing C++ for about three days now, but here's my code anyway:

clientData.h, two classes, ClientData extends Entity :

#pragma once

class Entity
{
public:
 int x, y, width, height, leftX, rightX, topY, bottomY;

 Entity(int x, int y, int width, int height);
 ~Entity();
};

class ClientData : public Entity
{
public:
 ClientData();
 ~ClientData();
};

and clientData.cpp, which contains the functions:

#include <iostream>
#include "clientData.h"
using namespace std;

Entity::Entity(int x, int y, int width, int height)
{
 this->x = x;
 this->y = y;
 this->width = width;
 this->height = height;

 this->leftX = x - (width/2);
 this->rightX = x + (width/2);
   this->topY = y - (height/2);
 this->bottomY = y + (height/2);
}

Entity::~Entity()
{
 cout << "Destructing.\n";
}

ClientData::ClientData()
{
 cout << "Client constructed.";
}

ClientData::~ClientData()
{
    cout << "Destructing.\n";
}

and finally, I'm creating a new ClientData with:

ClientData * Data = new ClientData(32,32,32,16);

Now, I'm not surprised my compiler shouts errors at me, so how do I pass the arguments to the right classes?

The first error (from MVC2008) is error C2661: 'ClientData::ClientData' : no overloaded function takes 4 arguments

and the second, which pops up whatever changes I seem to make is error C2512: 'Entity' : no appropriate default constructor available Thanks.

+1  A: 

Take a look at initialization lists.

Ozan
A: 

you would use the initializer list to call the constructor of the base class(note: it can also be used to call constructors of class objects in the object):

class Base
{
    private:
    int myVal;

    public:
    Base(int val)
    {
        myVal = val;
    }
};

class Heir : public Base
{
    private:
    std::string myName;

    public:
    Heir(std::string Name, int Val) : Base(Val)
    {
        myName = Name;
    }
};
Necrolis
+4  A: 

Currently the constructor for the Client data class wont work. You will need to make a constructor for Client data like:

ClientData(int x, int y, int width, int height): Entity(x, y, width, height)

if you want to call

new ClientData(32,32,32,16);
shuttle87
Not valid syntax.
KennyTM
That's perfectly valid syntax. It's the only way to solve this problem....
SoapBox
@Soap: The syntax was invalid when I write that comment. It was edited within 5 minutes and it's fine now.
KennyTM
@KennyTM Then why doesn't the post say it was edited? Stackoverflow typically marks edited answers as such.
luiscubal
@luis: http://meta.stackoverflow.com/questions/9090/is-there-an-editing-grace-period-on-answers-after-they-have-been-posted
KennyTM
+2  A: 

Use the constructor initializer to initialize bases and members:

struct Entity {
  int x, y, width, height, leftX, rightX, topY, bottomY;

  Entity(int x, int y, int width, int height);
};

Entity::Entity(int x, int y, int width, int height)
: x(x), y(y), width(width), height(height),
  leftX(x - (width / 2)), rightX(x + (width / 2)),
  topY(y - (height / 2))
{
  bottomY = y + (height / 2); // for members like leftX, rightX, topY,
  // and bottomY, assignment inside the ctor (instead of initialization)
  // can be appropriate
}


struct ClientData : Entity {
  ClientData();
  ClientData(int x, int y, int width, int height);
};

ClientData::ClientData() : Entity(0, 0, 0, 0) {}  // you may not even want a
// default ctor for this type

ClientData(int x, int y, int width, int height)
: Entity(x, y, width, height)
{}
Roger Pate
+2  A: 

First point

new ClientData(32,32,32,16);

wont work since the only constructor you have for ClientData takes no arguments. Constructors are not inherited in c++, you have to define the constructor again.

class ClientData : Entity
{
   public:
   ClientData(int a,int b,int c,int d);
   //...
}

Second is calling the constructor of the base class. Normally the compiler uses calls the non argument constructor of the base class, since Entity only has a constructor taking arguments this will fail - you have to make an explicit call to the entity constructor.

ClientData::ClientData(int a,int b, int c, int d)
: Entity(a,b,c,d)//Initializer list call base class constructor here
{
 //...
}
josefx
A: 

I did some changes to your code. It may help you a bit about C++ classes, members and constructors.

When you use inherited classes, you must call base class constructor with necessary parameters on derived class constructor:

ClientData::ClientData(int x, int y, int width, int height) : Entity(x, y, width, height)

Just an opinion: Don't use parameters names the same as class members. I usually use 'm_' prefix before class members for easy identification.

class Entity
{
public:
 int m_x, m_y, m_width, m_height, m_leftX, m_rightX, m_topY, m_bottomY;

 Entity(int x, int y, int width, int height);
 ~Entity();
};

class ClientData : public Entity
{
public:
 ClientData(int x, int y, int width, int height);
 ~ClientData();
};

Entity::Entity(int x, int y, int width, int height)
{
 m_x = x;
 m_y = y;
 m_width = width;
 m_height = height;

 m_leftX = x - (width/2);
 m_rightX = x + (width/2);
 m_topY = y - (height/2);
 m_bottomY = y + (height/2);
}

ClientData::ClientData(int x, int y, int width, int height) : Entity(x, y, width, height)
{
 cout << "Client constructed.";
}
Jorg B Jorge