#include <iostream>
#include <vector>
class Entity
{
public:
bool hinders_sight = false;
};
class Pillar : public Entity
{
public:
bool hinders_sight = true;
};
int main()
{
std::vector<Entity*> Entities;
Pillar pillar;
Entities.push_back(&pillar);
std::cout << pillar.hinders_sight << std::endl;
std::cout << Entities[0]->hinders_sight << std::endl;
return 0;
}
pillar.hinders_sight returns true (as it should)
but
Entities[0]->hinders_sight returns false.
How can I reach hinders_sight of pillar from the vector?
What is happening right now is that there are two variables called hinders_sight in your derived class, one from the base class and another of the derived class.
There are two main approaches to solve this problem here (I would not recommend keeping two separate variables for the same thing in your base and derived classes), either you can make the variable a protected/private variable in the base class and then offer functions to get and store the variable as needed, or you can make the get_hinders_sight() function virtual.
class Entity {
public:
Entity(bool hinders_sight_in = false)
: hinders_sight{hinders_sight_in} {}
bool get_hinders_sight() { return this->hinders_sight; }
private:
bool hinders_sight = false;
};
class Pillar : public Entity {
public:
Pillar() : Entity{true} {}
};
Or
class Entity {
public:
virtual bool get_hinders_sight() { return false; }
};
class Pillar : public Entity {
public:
bool get_hinders_sight() override { return true; }
};
Use a virtual bool HindersSight(){return hinders_sight;} as variables are not virtual.
Edit: Oh and make your variables protected or private to promote encapsulation. You could complete get rid of the variable and implement HindersSight() for each class to directly return true or false.
Related
#include <iostream>
using namespace std;
class ParentClass
{
public:
int id;
ParentClass(int id)
{
this->id = id;
}
void print()
{
cout << id << endl;
}
};
class ChildClass: public ParentClass
{
public:
int id;
ChildClass(int id): ParentClass(1)
{
this->id = id;
}
};
int main()
{
ChildClass c(2);
c.print();
return 0;
}
I run this C++ file and I get '1' as output, I want to know how should I write to get '2' as output ? Or say that how to access a redefined variable from a derived class.
You cannot access ChildClass::id from ParentClass::print. More generally: You cannot access members of a derived class, from a member function of the parent.
You can access ChildClass::id within the member functions of ChildClass.
ChildClass::id isn't a "redefined" variable. It is a separate, unrelated variable that happens to have the same identifier, but in different scope. There is no concept of "redefining" a member variable in a derived class, in C++.
I recommend considering, whether it makes sense for ChildClass to have two different ids.
Your ChildClass is doing some wrong or discutable stuff:
1. it's "shadowing" the int id member of ParentClass
2. it's calling the ParentClass constructor passing 1 (instead of "id")
3. it's using assignements in constructors instead of initializer lists
4. ParentClass::id visibility may be decreased from public to protected or private.
Try the following modified code:
#include <iostream>
class ParentClass
{
public:
int id;
ParentClass(int id) : id(id) {}
void print()
{
std::cout << id << std::endl;
}
};
class ChildClass: public ParentClass
{
public:
ChildClass(int id): ParentClass(id) {}
};
int main()
{
ChildClass c(2);
c.print();
return 0;
}
recently i have read some about pure virtual function concept in c++ and i wonder, given following code:
class First
{
public:
virtual void init() = 0;
protected:
bool initialized;
};
class Second : public First
{
public:
void init() { ((*someting*) ? (initialized=true) : (initialized=false));
};
if creator of First class wanted to ensure the implementation of init() MUST set initialized variable either true or false how can they do that? Is there an option to enforce implementation of pure virtual function to set any variable inherited from base class?
You can make init protected and have it return bool.
Then have a new initialize method which is public and also sets the initialized member.
Since init now has a return value, it must be set by anyone who implements derived classes.
class First
{
public:
void initialize() { initialized = init(); }
protected:
virtual bool init() = 0;
bool initialized;
};
class Second : public First
{
public:
bool init() { return (*something*); }
};
You cannot check if initialized has been set or not, because it cannot represent the third state "undefined".
Solution 1
Protect the pure virtual function, make it return the initialized value and call it via a non-virtual wrapper
class First
{
public:
void init()
{
initialized = initImplementation();
// check initialized here
}
protected:
virtual bool initImplementation() = 0;
bool initialized;
};
Solution 2
Change initialized to an enumeration with the states undefined, non-initialized, initialized, protect the pure virtual function and call it via a non-virtual wrapper, that then checks if the variable has been set:
class First
{
public:
void init()
{
initImplementation();
// check initialized here
}
protected:
virtual void initImplementation() = 0;
enum
{
undefined,
initialized,
uninitialized
} initialized;
};
Solution 3
Get rid of initialized, just throw an exception in init() if something goes wrong. The caller will then know that something went wrong.
As a sidenote, you can throw also from the constructor.
Well, while the direct answer to your question is no. There is some technique you can employ to get a guaranteed call of your init function.
Let's say you have the following base class:
class Base
{
public:
virtual void init() = 0;
private:
bool initialized = false;
};
void Base::init()
{
std::cout << "Called from base!\n";
initialized = true;
}
And the following derived:
class Derived: public Base
{
friend class Enforcer<Derived>;
public:
void init() override
{
std::cout << "Called from derived!\n";
}
private:
Derived()
{
}
private:
using BaseClass = Base;
};
Look at the private constructor and the friend declaration: you can no more create this class without help of the Enforcer class(this step is not really required but it will really force any user of the Derived class to use Enforcer). And now we need to write the Enforcer class, here it is:
template<typename T>
class Enforcer: public T
{
public:
template<typename... Args>
Enforcer(Args&&... arg): T(std::forward<Args>(arg)...)
{
}
void init() override
{
T::init();
T::BaseClass::init();
}
};
The whole example on the ideone.
Yes it has its drawbacks(you need to add some additional stuff to the Derived class) but it solves the requirement pretty neatly, in my opinion.
I haven't worked with derived classes and polymorphism in a while, and I can't figure out how to access a derived class data item.
// Quick example
class Base {
string data1; // data1 = "FOO"
};
class ChildA : public Base {
string data2;
};
int main() {
Base **list;
list = new Base*[1];
base[0] = new ChildA(// data2 = "BAR");
std::cout << base[0]->data1; // FOO
std::cout << base[0]->data2; // Error; no member named "data2" in Base
Is it possible to retrieve the derived data from the base class array?
When you're looking at an instance of a derived class through a pointer to the base class, you can only see the members of the base class, because generally, you wouldn't know what subtype instance you are looking at. The point of polymorphism and virtual functions is that in many cases, you can work with subtype instances without knowing their actual type. For instance, if you want to print information about an instance, and you want data2 to be included when you print a ChildA, you would create a virtual toString() function in Base and override it in ChildA to include data2. Then, you can call toString() without knowing the actual type, and if your instance is actually a ChildA, you'll get data2.
class member variable by default is private.
by using base class pointer, you can not get derived class member var at all.
If you would like to do so, you may want to implement virtual getter function, it will help you getting private member function from derived class.
If the base class interface must have knowledge of data potentially held in a derived class, here is one of the few ways that is not horribly dangerous.
#include <iostream>
#include <vector>
#include <utility>
#include <memory>
#include <stdexcept>
using namespace std;
class Base {
public:
Base(std::string d1 = {"FOO"} ) : _data1 { std::move(d1) } {}
virtual ~Base() = default; // because polymorphism without a virtual base class is naughty
const string& data1() const { return _data1; }
virtual bool has_data2() const { return false; }
virtual const string& data2() const {
throw invalid_argument {"I don't have data2"};
};
private:
string _data1; // data1 = "FOO"
};
class ChildA : public Base {
public:
ChildA(std::string d2, std::string d1 = {"FOO"})
: Base { std::move(d1) }
, _data2 { std::move(d2) }
{}
bool has_data2() const override { return true; }
const std::string& data2() const override {
return _data2;
};
private:
string _data2;
};
int main()
{
vector<unique_ptr<Base>> bases;
bases.push_back(unique_ptr<Base>(new ChildA("bob")));
bases.push_back(unique_ptr<Base>(new Base("not foo")));
for(const auto& p : bases) {
cout << p->data1() << ", " << (p->has_data2() ? p->data2() : "no data 2") << endl;
}
return 0;
}
#include <iostream>
class EquationOfMotion
{
public:
// other attributes
virtual void findNextTimeStep() = 0;
};
class SystemModel
{
public:
EquationOfMotion* p_eom;
// other atributes
SystemModel(EquationOfMotion* new_p_eom)
{
p_eom = new_p_eom;
}
};
class VehicleEquationOfMotion: public EquationOfMotion
{
public:
VehicleEquationOfMotion(...){/* initialise attribute*/}
virtual void findNextTimeStep(){}
};
class Vehicle: public SystemModel
{
// ???? Implementation ?????
}
Vehicle is a specialization of SystemModel where p_eom points to VehicleEquationOfMotion.
I would like to initialise, an instance of VehicleEquationOfMotion and point to it p_eom in Vehicle. I want it to be defined only within the scope of Vehicle, and at the same time, not to use heap.
Is it even possible to reside VehicleEquationOfMotion object inside Vehicle without using the heap? (If not, please suggest where the design has gone wrong).
Might be helpful: I thought about the implementation in this question but ran into trouble (see the question).
If I got your question correctly, then do it like this:
class FooChild : public FooParent
{
public:
FooChild (int pX):m_BarChild(pX), FooParent(&m_BarChild) // point p_barPar to instance of BarChild (i.e. m_BarChild)
{
}
private:
BarChild m_BarChild; // instance of BarChild resided in the stack(not the heap) and is local to FooChild
}
If you want to have FooParent.p_barPar to be pointing to a BarChild that resides inside FooChild, you might need to add a default ctor to FooParent and a method as follows as well: set_p_barPar(BarChild* new_p_bar){p_barPar = new_p_bar;}. So you get:
class FooParent
{
public:
BarParent* p_barPar;
FooParent (){}
FooParent (BarChild* new_p_bar)
{
p_barPar = new_p_bar;
std::cout << p_barPar->x << std::endl;
}
protected:
set_p_barPar(BarChild* new_p_bar)
{
p_barPar = new_p_bar;
}
}
Then you can implement FooChild:
class FooChild : public FooParent
{
public:
FooChild(int new_x, BarChild* new_p_bar):_bar_child(new_x)
{
set_p_barPar(&_bar_child);
}
private: //? Depends on your plans
BarChild _bar_child();
}
Use a class template.
class EquationOfMotion { ... };
template <typename EOM>
class SystemDynamics
{
EOM EquationOfMotion;
...
};
class VehicleEquationOfMotion : public EquationOfMotion { ... };
class Vehicle : public SystemDynamics<VehicleEquationOfMotion> { ... };
May be this is what you want. But the design is not safe. You are passing the pointer to a uninitialized object.
class Vehicle: public SystemModel
{
public:
Vehicle(): SystemModel(&_vem)
{
}
VehicleEquationOfMotion _vem;
}
However, it is safer to do the following:
class SystemModel
{
public:
EquationOfMotion* p_eom;
// other atributes
SystemModel()
{
}
};
class Vehicle: public SystemModel
{
public:
Vehicle(): SystemModel(&_vem)
{
p_eom = &_vem;
}
VehicleEquationOfMotion _vem;
};
My question might not be too correct... What I mean is:
class MyClass
{
public:
MyClass()
{
}
virtual void Event()
{
}
};
class FirstClass : public MyClass
{
string a; // I'm not even sure where to declare this...
public:
FirstClass()
{
}
virtual void Event()
{
a = "Hello"; // This is the variable that I wish to pass to the other class.
}
};
class SecondClass : public MyClass
{
public:
SecondClass()
{
}
virtual void Event()
{
if (a == "Hello")
cout << "This is what I wanted.";
}
};
I hope that this makes at least a little sense...
Edit: _This changed to a.
What you need to do is make SecondClass inherit from FirstClass and declare _This as protected.
class FirstClass : public MyClass
{
protected:
string _This;
public:
and
class SecondClass : public FirstClass
What you got doesn't make sense because classes can only see members and functions from their parents (MyClass in your case). Just because two class inherit from the same parent does not mean they have any relation or know anything about each other.
Also, protected means that all classes that inherit from this class will be able to see its members, but nobody else.
I guess that you need something like this (for a sake of simplicity, I've omitted all the unnecessary code):
class Base{
public:
~Base(){}
protected:
static int m_shared;
};
int Base::m_shared = -1;
class A : public Base{
public:
void Event(){
m_shared = 0;
}
};
class B : public Base{
public:
void Event(){
if (m_shared == 0) {
m_shared = 1;
}
}
};
int _tmain(int argc, _TCHAR* argv[])
{
A a;
B b;
a.Event();
b.Event();
return 0;
}
To explain above, I'll explain the static data members:
Non-static members are unique per class instance and you can't share them between class instances. On the other side, static members are shared by all instances of the class.
p.s. I suggest that you read this book (especially Observer pattern). Also note that above code is not thread-safe.