DizzyDoo
DizzyDoo

Reputation: 1489

C++ Inheritance and Constructors

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.

Upvotes: 2

Views: 4152

Answers (6)

Jorg B Jorge
Jorg B Jorge

Reputation: 1119

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.";
}

Upvotes: 0

josefx
josefx

Reputation: 15656

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
{
 //...
}

Upvotes: 3

Roger Pate
Roger Pate

Reputation:

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)
{}

Upvotes: 2

shuttle87
shuttle87

Reputation: 15964

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);

Upvotes: 5

Necrolis
Necrolis

Reputation: 26181

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;
    }
};

Upvotes: 0

Ozan
Ozan

Reputation: 4415

Take a look at initialization lists.

Upvotes: 1

Related Questions