"Identifier is undefined" error in accessing "protected" data in sub class - c++

Please have a look at the following code
GameObject.h
#pragma once
class GameObject
{
protected:
int id;
public:
int instances;
GameObject(void);
~GameObject(void);
virtual void display();
};
GameObject.cpp
#include "GameObject.h"
#include <iostream>
using namespace std;
static int value=0;
GameObject::GameObject(void)
{
value++;
id = value;
}
GameObject::~GameObject(void)
{
}
void GameObject::display()
{
cout << "Game Object: " << id << endl;
}
Round.h
#pragma once
#include "GameObject.h"
class Round :
public GameObject
{
public:
Round(void);
~Round(void);
};
Round.cpp
#include "Round.h"
#include "GameObject.h"
#include <iostream>
using namespace std;
Round::Round(void)
{
}
Round::~Round(void)
{
}
void display()
{
cout << "Round Id: " << id;
}
I am getting 'id' : undeclared identifier error in Round class. Why is this? Please help!

In this function:
void display()
{
cout << "Round Id: " << id;
}
You are trying to access a variable named id inside a non-member function. The compiler cannot resolve that name, because id is not the name of any global nor local variable, therefore you get an error complaining that the identifier was not declared.
If you meant to make display() a member function of Round(), you should have declared it as such:
class Round : public GameObject
{
public:
Round(void);
~Round(void);
void display(); // <==
};
And defined it this way:
void Round::display()
// ^^^^^^^
{
...
}
This way, function Round::display() would override the virtual function GameObject::display().

You declared a globally scoped method named display in your Round.cpp file. Edit your header and cpp like this:
Round.h
#pragma once
#include "GameObject.h"
class Round :
public GameObject
{
public:
Round(void);
virtual ~Round(void);
virtual void display(void);
};
Round.cpp
#include "Round.h"
#include "GameObject.h"
#include <iostream>
using namespace std;
Round::Round(void)
{
}
Round::~Round(void)
{
}
void Round::display()
{
cout << "Round Id: " << id;
}
Note - you should make the destructor in GameObject virtual

Related

Empty constructor and value passing problem

When I create a class A object with a reference to class C, class B gives the error of:
Error C2512 'A': no appropriate default constructor available
Class A
class A
{
public:
C* cPointer;
A(C* arg)
{
cPointer = arg;
}
};
Class B
class B:
public A
{
public:
B()
{
}
};
If I add an empty constructor to class A it doesn't give errors but when I try to access cPointer it returns an empty address of 0000000000;
A()
{
}
How can I solve this problem?
Edit: example
int main()
{
C cObject;
A a(&cObject);
return 0;
}
Result: Severity Code Description Project File Line Suppression State
Error C2512 'A': no appropriate default constructor available
As I mentioned before if I put empty constructor to A it works but i cant use cPointer because it set to 0.
in class B:
cout << "Poniter: " << cPointer << endl;
result:
Pointer: 0000000000000000
Okay here is the actual code:
Skill.h (class C in example)
#pragma once
#include <iostream>
#include <vector>
#include "Unit.h"
using namespace std;
class Skill
{
public:
Unit* unitPtr;
Skill()
{
}
Skill(Unit* unit)
{
unitPtr = unit;
}
void SetUnit(Unit* unit)
{
unitPtr = unit;
}
vector <Skill *> attacks;
vector <Skill *> utilities;
vector <Skill *> movement;
};
Unit.h (class A in example)
#pragma once
#include <iostream>
#include <vector>
#include <stdlib.h>
#include <time.h>
using namespace std;
class Skill;
class Unit
{
public:
Skill* skillPtr;
Unit(Skill* skill)
{
skillPtr = skill;
}
void Setup();
string name;
vector <Unit* > heroes;
vector <Unit* > monsters;
};
Hero.h (class B in example)
#pragma once
#include "Unit.h"
class Hero :
public Unit
{
public:
Hero() : Unit(skillPtr)
{
cout << "Pointer: " << skillPtr << endl;
}
};
Main
int main()
{
Skill skill;
Unit unit(&skill);
skill.SetUnit(&unit);
unit.Setup();
return 0;
}
class B: public A {
B() { }
}
When a child class's constructor is called, it first initializes its parent portion by calling a parent constructor. Since you didn't specify one here, the B constructor is trying to call the default A constructor, but one doesn't exist!
To call the constructor you made explicitly, you can do:
class B: public A {
B(): A(Some_C_Pointer) { }
}

How to use abstract class' children instances through methods?

I have an abstract class Player and its children AI and Human. In my main, when I create two objects Human and AI it works fine. But once I use them as parameters in a function that is waiting for Player pointer type, then their type is no longer AI and Human but both are Player objects.
Game.hpp :
#include "Player.hpp"
#include "Human.hpp"
class Game {
private:
Player *j1, *j2;
public:
Game();
Game(Player*, Player*);
void setP1(Player*);
void setP2(Player*);
Player* getP1();
Player* getP2();
};
Game.cpp :
#include "Game.hpp"
Game::Game(){
}
Game::Game(Player *pp1, Player *pp2){
p1 = pp1;
p2 = pp2;
}
void Game::setP1(Player *pp1){
p1 = pp1;
}
void Game::setP2(Player *pp2){
p2 = pp2;
}
Player* Game::getP1(){
return p1;
}
Player* Game::getP2(){
return p2;
}
Player.hpp :
#ifndef PLAYER_H
#define PLAYER_H
#include <string>
using std::string;
class Player {
protected:
string nom;
int age;
public:
Player();
Player(string, int);
void setNom(string);
void setAge(int);
string getNom();
int getAge();
virtual void upAge() = 0;
};
#endif
Here is the main.cpp :
#include "Player.hpp"
#include "Human.hpp"
#include "Game.hpp"
#include <iostream>
#include <string>
using std::cout;
using std::endl;
using std::string;
int main(){
Player *j;
Human h;
Game Game;
cout << typeid(h).name() << endl;
Game.setJ1(&h);
cout << typeid(Game.getJ1()).name() << endl;
return 0;
}
I would like the two cout to display the same result. But the first displays Human, and the second displays Player. How can I handle this ?
EDIT 1 : added Player.hpp file.
Base class Player must contain a virtual function to get the type name as derived class.
check typeid below example from cpp reference.
#include <iostream>
#include <string>
#include <typeinfo>
struct Base {}; // non-polymorphic
struct Derived : Base {};
struct Base2 { virtual void foo() {} }; // polymorphic
struct Derived2 : Base2 {};
int main() {
// Non-polymorphic lvalue is a static type
Derived d1;
Base& b1 = d1;
std::cout << "reference to non-polymorphic base: " << typeid(b1).name() << '\n';
Derived2 d2;
Base2& b2 = d2;
std::cout << "reference to polymorphic base: " << typeid(b2).name() << '\n';
}
Possible output:
reference to non-polymorphic base: 4Base
reference to polymorphic base: 8Derived2

C++ override function from same base template class with multiple inheritance ambiguous function call

I need to call init(int* iNumber) function which is derived from the base class.
BaseClass.h
#pragma once
#include "stdafx.h"
template <class T>
class BaseClass
{
public:
BaseClass() {}
virtual ~BaseClass() {}
virtual void init(T* object) = 0;
};
ChildClass.h
#pragma once
#include "BaseClass.h"
class ChildClass : public BaseClass<int>, public BaseClass<float>
{
public:
ChildClass() {}
virtual ~ChildClass() {}
};
ChildClassImpl.h
#pragma once
#include "ChildClass.h"
class ChildClassImpl : public ChildClass
{
public:
ChildClassImpl();
virtual ~ChildClassImpl();
private:
void init(int* iNumber) override;
void init(float* fNumber) override;
};
ChildClassImpl.cpp
#include "stdafx.h"
#include <iostream>
#include "ChildClassImpl.h"
ChildClassImpl::ChildClassImpl(){}
ChildClassImpl::~ChildClassImpl(){}
void ChildClassImpl::init(int* iNumber)
{
std::cout << "Integer constructor: " << *iNumber << std::endl;
}
void ChildClassImpl::init(float* fNumber)
{
std::cout << "Float constructor: " << *fNumber << std::endl;
}
MainClass
#include "stdafx.h"
#include <iostream>
#include "ChildClassImpl.h"
using namespace std;
int main()
{
ChildClass* childClass = new ChildClassImpl();
int x = 10;
childClass->init(&x);
cout << "Test" << endl;
getchar();
return 0;
}
At compile time this is gives the error
Severity Code Description Project File Line Error
(active) "BaseClass<T>::init [with T=int]" is
ambiguous ConsoleApplication4 d:\Learning\ConsoleApplication4\ConsoleApplication4\ConsoleApplication4.cpp 14
What am I doing wrong here? How could I fix it with minimal changes?
This code fails because C++ performs name lookup before overload resolution and access control check. That is first step would be to determine to which class scope init belongs to. And in this case result would be ambiguous because init could refer to either BaseClass<int>::init or BaseClass<float>::init. Introducing an extra using declaration will bring both of those functions into ChildClass scope:
class ChildClass : public BaseClass<int>, public BaseClass<float>
{
public: using BaseClass<int>::init;
public: using BaseClass<float>::init;
So name lookup will determine that init refers to ChildClass::init and compiler will proceed to overload resolution.
Alternatively you can perform a cast (which is definitely not as convenient):
static_cast<BaseClass<int> *>(childClass)->init(&x);

c++ class inheritance, identifier undefined

I'm new to object programming and to c++.
I'm applying what is taught in SoloLearn c++ course about class inheritance.
Class enemy: enemy.h
class enemy
{
public:
enemy();
~enemy();
void setAttackPower();
protected:
int aP;
};
enemy.cpp:
#include "enemy.h"
#include <iostream>
using namespace std;
enemy::enemy()
{
cout << "constructor" << endl;
}
enemy::~enemy()
{
cout << "destructor" << endl;
}
int aP=0;
void setAttackPower(int a) {
aP = a;
}
class ninja, that inherits from enemy:
ninja.h:
#include "enemy.h"
class ninja: public enemy
{
public:
ninja();
~ninja();
void attack();
};
ninja.cpp:
#include "ninja.h"
#include <iostream>
using namespace std;
ninja::ninja()
{
}
ninja::~ninja()
{
}
void attack() {
cout << "Ninja attack " << aP << endl;
}
and the error is:
identifier "aP" is undefined. I can't see the problem. Can anyone help me?
enemy.cpp
int aP=0;
You created 2 values with same name: 1st belongs to class and the 2nd is a global value. The compiler cannot deside which one you are trying to use.

c++, Base class constructor seperate declearation and implementation

In my C++ program I have separate .h and .cpp files and everything is working so far except when I want to use a base class constructor for a derived class. It is working but only if I put the function definition if the class deceleration.
Here's the working code for the .h file.
#include <iostream>
using namespace std;
class property
{
public:
property();
property(const property & src);
property(int src);
~property();
virtual int disp() const = 0;
int get_ownable();
private:
protected:
int ownable;
};
class rr : public property
{
public:
rr();
rr(const rr & src);
rr(int src):property(src)
{cout << "\nderived class was called\n";};
~rr();
virtual int disp() const;
private:
protected:
};
The imp.cpp (implementation) file is
#include "head.h"
#include <iostream>
using namespace std;
//property class implimentations
property::property()
{
ownable = 0;
}
property::property(const property & src)
{
ownable = src.ownable;
}
property::property(int src)
{
ownable = src;
cout << "\nparent class called\n";
}
property::~property()
{
}
int property::get_ownable()
{
return ownable;
}
rr::rr()
{}
rr::rr(const rr & src)
{
ownable = src.ownable;
}
/*
rr::rr(int src):property(src)
{
cout << "\nderived class was called\n";
}
*/
rr::~rr()
{
}
int rr::disp() const
{
}
There is other code but it is working fine and not connected to this. The output is
parent class called
derived class was called
So that works just fine but if I un-comment out the function in the .imp file and remove the declaration in the .h
rr(int src):property(src);
I get the error
head.h: IN constructor 'rr::rr(int)':
head.h 113: error: expeted '{' at end of input
imp.cpp: at global scope:
imp.cpp:348:error: redefiniton of 'rr::rr(int);
head.h.113: error: 'rr::rr(int); previousle defined here
All the examples I can find on line of how to do this do it with all the functions defined in the class declaration. I can't find any examples of how to do it with 2 files. Can anyone tell me how to define the base class constructor call in a separate file?
I am on a Linux system using g++ compiler.
Like this
BaseClass.h
#pragma once
class BaseClass {
public:
BaseClass(int a);
private:
int a_private;
};
BaseClass.cpp
#include "BaseClass.h"
#include <iostream>
using std::cout;
using std::endl;
BaseClass::BaseClass(int a) {
cout << "Base class constructor called" << endl;
this->a_private = a;
}
Derived.h
#pragma once
#include "BaseClass.h"
class Derived : public BaseClass {
public:
Derived(int a);
private:
int a_private;
};
Derived.cpp
#include "Derived.h"
#include <iostream>
using std::cout;
using std::endl;
Derived::Derived(int a) : BaseClass(a) {
cout << "Derived class constructor called" << endl;
this->a_private = a;
}
main.cpp
#include "BaseClass.h"
#include "Derived.h"
int main() {
Derived d(2);
return 0;
}
Compiling with the command
g++ main.cpp Derived.cpp BaseClass.cpp and running will result in the following output
Base class constructor called
Derived class constructor called
As mentioned in the comments (credits #IgorTandetnik), initializer lists should be used only in the implementation file. Not in the header file (provided the class is not templated).