After reading up on class tutorials on the C++ site, I have learned the following piece of code which I then tried to work with:
class CVector {
public:
int x,y;
CVector () {};
CVector (int,int);
CVector operator + (CVector);
};
CVector::CVector (int a, int b) {
x = a;
y = b;
}
After which I wrote the following code, in order to learn to program C++ classes efficiently and to write cleaner code:
class Player {
public:
string name;
int level;
};
Player::Player(int y) {
level = y;
}
However it gives me error C2511: 'Player::Player(int)' : overloaded member function not found in 'Player'.
I have searched for the error but I did not find how to fix it. What's wrong with this code?
You need to declare the single parameter construction:
class Player {
public:
Player(int y);
std::string name;
int level;
};
Once you do this, there will no longer be a compiler synthesized default constructor, so if you need one, you would have to write your own. Also consider making the single parameter constructor explicit if you do not want implicit conversions from int.
class Player {
public:
explicit Player(int y); // no implicit conversions from int
Player() :name(), int() {} // default constructor and implementation
std::string name;
int level;
};
Also, prefer the constructor initialization list to assigning values in the constructor body, if possible. There are plenty of SO questions on that topic so I won't elaborate here. This is how you would do it:
Player::Player(int y) : level(y) {
}
Add declaration inside your class for this constructor.
class Player {
public:
Player( int y );
string name;
int level;
};
class Player
{
public:
Player(int );
string name;
int level;
};
Related
I am having difficulty trying to implement a constructor for my child class. I understand the purpose of the constructor is to set the states of the class to the values passed? am I correct in this?
I am getting an error;
no matching function for call to 'superclass'
My question is do I have to link my constructor for a child class to the superclass? what is the relationship in terms of constructors between the two classes?
#include<iostream>
using namespace std;
class Buildings
{
private:
float price, area;
string city;
public:
Buildings(float, float, string);
// Buildings(float, float, float);
void virtual display();
void virtual getprice(float);
void virtual getcity(string);
void virtual getarea(float);
};
Buildings::Buildings(float b_price, float b_area, string b_city):price(b_price), area(b_area), city(b_city)
{
}
void Buildings::display()
{
cout<<"The city, price and area(sqft) of the building are: "<<city<<endl<<price<<endl<<area;
}
void Buildings::getprice(float aprice)
{
price = aprice;//potential error handling
}
void Buildings::getarea(float asize)
{
area = asize;
}
void Buildings::getcity(string acity)
{
city = acity;
}
class Apartment:public Buildings
{
private:
float numtennants;
float rent;
float rentpr;
public:
Apartment(float numres, float numrent, float numrentpr);
void virtual display();
void virtual avgrent(float);
void virtual totrent(float);
void virtual totres(float);
};
Apartment::Apartment(float numres, float numrent, float numrentpr):numtennants(numres),rent(numrent),rentpr(numrentpr)
{}
void Apartment::display()
{
Buildings::display();
}
Buildings doesn't have a default constructor. You must explicitly call the only Buildings constructor that exists, passing along the suitable arguments.
If you want do disallow public default-construction of Buildings objects, but allow child-classes to use it, you can make a default constructor that is protected. Like
class Buildings
{
public:
// Public constructor, only way to construct object of this class
// for the general public
Buildings(float, float, string);
// Other public functions...
protected:
// Default constructor, which initializes the private members
// to some suitable values
// Only usable by child-classes
Buildings()
: price(0), area(0), city("")
{}
private:
float price, area;
string city;
};
You must call the parent class's constructor in your child class's member initializer list.
struct A {
A(int a) : a_(a) {}
int a_;
};
struct B : public A {
B(int a, int b) : A(a), b_(b) {}
int b_;
};
I want provide a class with a member function that will initialize the all member of class separately.
e.g.
#include <iostream>
using namespace std;
int x = 10;
class my{
public:
my():init{}
int &i;
void init()
{
i = x;
}
};
int main()
{
my m;
return 0;
}
I know if I can use "class my : i(init())" will work, but I have some special purpose to intialize like above.
However in above example, I'm getting following error:
class ‘my’ does not have any field named ‘initMy’.
How to resolve this?
If you are trying to write a constructor for class my, then it must be named with the class name. The following will work assuming that initMy is the name of another class that you are trying to subclass.
class my : initMy
{
public:
int i;
my() {
i = 10;
}
};
You might try to pre-initialize all the fields, then calling the initializing function inside the constructor:
class my {
public:
int i;
void initMy() {
i = 10;
}
my() : i(0) { initMy(); };
};
You could also (in C++11) define a bizarre signature for a private constructor, and delegate a constructor to it
class my {
private:
void initMy () { i=10; };
enum privateen {privatev};
my(enum privateen) : i(0) { initMy(); };
public:
my() : my(privatev) {};
int i;
};
Actually, I believe that your initialization should be in a constructor, not in some other function.
Few things to clarify here.
Member initialization list is for initialize members (mostly same purpose of the constructor).In initialize list nothing to do with member functions. in this example age(newAge) is not a function. It is initializing age variable.
class Man{
private:
int age;
string name;
public:
Man(int newAge):age(newAge),name("Jhon"){}
};`
You can use constructor to initialize the members of the class.
class Man{
private:
int age;
string name;
public:
Man(int newAge)
{
age = newAge;
name = "Jhone";
}
};
Alternatively you can use a init method to do initialization, if you have some issue to use constructor.
class Man{
private:
int age;
string name;
public:
Man(){}
init(int newAge, string newName)
{
age = newAge;
name = newName;
}
};
If you need to set the value of only one member in a class, you have to use a setter method
class Man{
private:
int age;
string name;
public:
Man(){}
setAge(newAge)
{
age = newAge;
}
setName(newName)
{
name = newNAme
}
};
edit:
class Man{
private:
int age;
string name;
public:
Man(initAge, initName)
{
setValues(initAge, initName);
}
setValues(newAge, newName)
{
age = newAge;
name = newName;
}
};
int main()
{
Man goodMan(34,"Jhon");
goodMan.setValues(45,"Kevin");
}
I am trying to deal with friend class for the first time. I wrote the code below:
class Kind{
private:
friend class Type;
int x;
public:
Kind(){ x=0; }
void setX(int X) { x =X; }
int getX() { return x; }
};
class Type: public Kind {
public:
friend class Kind;
Type(){ }
Kind root;
root.x=3;
};
The compiler tells me that I can not do root.x=3;, What is the problem??
The problem is your trying to execute a statement in a place where the compiler is expecting member declarations. Try putting it into a method
class Type : public Kind {
...
void Example() {
Kind root;
root.x = 3;
}
};
You cannot do the assignment as part of the class declaration. Do it in a member function instead.
I was just wondering on the most efficient way of setting inherited members was and if the following code is alright to use:
This is the declaration of the base class:
class cEntity{
private:
int X, Y;
int Height, Width;
public:
cEntity();
cEntity(int x,int y,int h,int w);
~cEntity();
void setX(int x){X=x;};
void setY(int y){Y=y;};
void setCoords(int x, int y){X=x;Y=y;};
void setHeight(int h){Height = h;};
void setWidth(int w){Width = w;};
void setArea(int h, int w){Height=h;Width=w;};
int getX(){return X;};
int getY(){return Y;};
//void getXY(int,int);
int getHeight(){return Height;};
int getWidth(){return Width;};
//void getArea(int,int);
};
and here is the constructor of the derived class:
cOrganism::cOrganism () {
setCoords(0,0);
setArea(0,0);
Name = "UNKNOWN";
Health = 100;
MaxHealth = 100;
HealthHiRange =100;
HealthLoRange = 100;
};
So. Is is alright to call the setCoords() and setArea() in the derived class' constructor?
It's alright, but you can do much better by calling the base constructor:
cOrganism::cOrganism() : cEntity(0, 0, 0, 0) {
// other stuff
}
In fact, you should initialize your new, derived members the same way:
cOrganism::cOrganism()
: cEntity(0, 0, 0, 0),
Name("UNKNOWN"),
Health(100),
...
{
}
(You might also want to read up a bit on general C++ class design: If you expose getters and setters to all your private variables, something isn't quite right. A class is supposed to encapsulate a model, while you're doing essentially the opposite. But that's not a technical error.)
Much better to call it like this:
cOrganism::cOrganism () : cEntity(0,0,0,0) {
Name = "UNKNOWN";
Health = 100;
MaxHealth = 100;
HealthHiRange =100;
HealthLoRange = 100;
}
Or even better:
cOrganism::cOrganism ()
: cEntity(0,0,0,0), Name("UNKNOWN"), Health(100),
MaxHealth(100), HealthHiRange(100), HealthLoRange(100)
{}
That way the base class members are set as the base class implementation is constructed.
If the default constructor of the base class already intializes it to good values you don't have to do it all.
Otherwise the good solution is something like below.
class A
{
int x;
public:
A( int xin) :x(xin) {}
};
class B : public A
{
int y;
public:
B( int xin , int yin ) :A(xin) , y(yin) {}
};
Notice A(xin) in B constructor. This will called pass xin to the A constructor.
If you have something like integers it doesn't really matter what you do. But if A::X was actually a heavy weight object. With your approach A::x will be constructed once with default constructor and then assigned again when setCoords() is called from derived class constructor. My solution will ensure A::x* is only constructed once and that too with all the right value of its parameters.
More details here
Is it possible to create an object of a class, inside a class definition, without using default constructor?
class Vector3D {
public:
Vector3D(int x, int y, int z);
virtual ~Vector3D();
private:
int m_X;
int m_y;
int m_z;
};
class CustomClass {
private:
Vector3D m_Vec(50,50,50); //error
};
Yes, this can be done, but the syntax is different:
class Vector3D {
public:
Vector3D(int x, int y, int z);
virtual ~Vector3D();
private:
int m_X;
int m_y;
int m_z;
};
class CustomClass {
private:
Vector3D m_Vec;
public:
CustomClass(): m_Vec(50,50,50) {}
};
class CustomClass {
private:
Vector3D m_Vec;
public:
CustomClass() : m_Vec(50,50,50) {}
}
In the (now current) C++11 standard you can actually do that using uniform-initialization and Non-static data member initializers (N2756):
class CustomClass {
private:
Vector3D m_Vec{50,50,50};
};
Now, the problem is that not all compilers have support for all of the new features. In particular gcc 4.7 is the first of the gcc versions to support this form of initialization.