In c++, Is there a standard way to create a function in a base class that can use the variables of derived classes?
class Foo{
private:
int x;
public:
Foo(){
x = 2;
}
void print(){
std::cout << x << std::endl;
}
};
class Derived : public Foo{
private:
int x;
public:
Derived(){
x = 4;
}
};
void main()
{
Derived a;
a.print();
}
This code prints the variable of the base class ( 2 ). Is there a way to make a function used by many derived classes to use the class's private variables without passing them as parameters?
Edit: My intentions are, to avoid writing the same code for each derived class.
For example, I want a get_var() in all, but this function should return the variable of that own class. I know I can make virtual and override, but I was looking for a way that I don't need to write again and again.
No, it is not possible for the base class to access anything in the derived class directly. The only way for a derived class to share anything with its base class is by overriding virtual member functions of the base class.
In your case, however, this is not necessary: the derived class can set variable x in the base class once you make it protected, and drop its own declaration as unnecessary:
class Foo{
protected: // Make x visible to derived classes
int x;
public:
Foo(){
x = 2;
}
void print(){
std::cout << x << std::endl;
}
};
class Derived : public Foo{
public:
Derived(){
x = 4;
}
};
Related
I currently have the following (simple problem).
I would like to access a public member of the base class from a nested class. Apparently it doesn't work that easily...
What is the correct solution here?
Do I have to pass *this to the nested class within the derived class?
Thank you for the food for thought!
#include <iostream>
class base
{
public:
virtual void update() = 0;
void drawCircle(const int& num) const { std::cout << "Base Clase: Circle " << num << " completed..." << std::endl; };
private:
};
class derived : public base
{
public:
class nestedClass
{
public:
void drawSomeCircle() const {
drawCircle(1); // does not work!
drawCircle(2); // does not work!
drawCircle(3); // does not work!
}
private:
};
void update() override
{
// make some graphic stuff
myInnerNestedClass.drawSomeCircle();
// access base class member drawCircle from here --> is working
drawCircle(4);
}
nestedClass myInnerNestedClass;
private:
};
int main()
{
derived oneDerivedClass;
oneDerivedClass.update();
return 0;
}
Do I have to pass *this to the nested class within the derived class?
Yes. nestedClass doesn't know to whom drawCircle(const int&) belongs unless it's in a global or outer namespace scope.
Once you pass a *this object of derived to nestedClass, it can even access its private members as well.
The compiler keeps saying 'class A' has no member named 'foo'.
I am trying to use a function from a derived class with a pointer. Here is my code:
class A{
.....
};
class B:public A{
virtual void foo() = 0;
};
class C:public B{
....
public:
void foo(){
....
}
};
I have a table of A pointers named Table and when trying
Table[j]->foo()
I am getting the compiler error.
What should I do except cast?
You have a compilation error because function foo is not declared in class A.
You can declare it as pure virtual in A like this:
class A {
virtual void foo() = 0;
};
In derived classes you don't have to declare foo as explicitly virtual. If only C is a concrete class, you don't have to declare foo in class B at all.
If your example if you know that in your array of pointers to A you have only instances of class C you can explicitly cast to pointer to C but it is a sign of poor design and I don't recommend it:
static_cast<C*>(Table[j])->foo()
If you have a pointer to a base and want to access a member of the derived type you have to cast so you have a pointer to the derived type, either that or as in your case add foo() as a virtual member to the base.
class A
{ ... };
class B : public A:{
{
public:
virtual foo() { std::cout << "B::foo" << std::endl; }
};
class C : public B
{
public:
void foo() { std::cout << "C::foo" << std::endl;
};
...
A * arr[8];
for(int i = 0; 8>i; ++i)
arr[i] = new C;
((B*)arr[0])->foo(); // will print "C::foo\n"
But if you added virtual void foo() = 0; to A then you could just do arr[0]->foo() and it would still print C::foo
I have a base class
class base {
public:
base();
int someData;
virtual void foo(){
std::cout << someData;
}
};
and a few derived classes like
class derived : public base {
public:
derived();
void foo(){
std::cout << someData * 5;
}
};
Basically they have the same kind of data but the operations on this data are different.
I have another class that doesn't need to know the details of my object, all it needs to do is to set data and call the derived foo().
class useData {
public:
useData();
base x;
int do() { x.someData = 5; return x.foo(); }
};
I want "useData" to be as generic as possible so I'm using the base class instead of the derived class in its definition.
Of course in this scenario it will call the base method and not the derived one. How can I rewrite my code or make it automatically (without type checking or similar) call the derived method?
Thank you
To use polymorphism you need some pointer or references. So in useData the variable x should be declared as a base *. Afterward, you can create is using a new with any derived class. Polymorphism will perform as expected..
I learnt the work of virtual functions: if the inherited classes inherit a function from the base class, and it is custom for each ones, I can call these functions with pointers that point to the base class, this way:
BaseClass* PointerName = &InheritedClassObject;
But what about variables? I found this question on the site that tells: I can't create virtual variables in C++. My experience proves it: for variables, Visual C++ says: 'virtual' is not allowed.
Then, what is the way to reach the value of a(n inherited) variable that belongs to an inherited class by using base class pointers?
Based off your comment, I think what you are trying to ask if how do child classes access their parent's variables. Consider this example:
class Parent
{
public:
Parent(): x(0) {}
virtual ~Parent() {}
protected:
int x;
};
class Child: public Parent
{
public:
Child(): Parent(), num(0) {}
private:
int num;
};
void Child::foo()
{
num = x; //Gets Parent's x,
}
NB: If you define an x in Child, that masks the x in Parent. So, if you want to get the x in Parent, you would need: Parent::x. To simply get x from a Child c, you use c.x if x is public or use a getter if x is protected or private:
int Child::getNum()
{
return num;
}
You don't. Virtual functions use them, do whatever needs to be done and return result if needed.
You can't use any function, data member of an inherited class if it's casted back to base class. However, you can alter those variables with virtual functions. Example:
#include <iostream>
class BaseClass {
public:
BaseClass() {}
virtual void do_smth() = 0;
private:
};
class InheritedClass: public BaseClass {
public:
InheritedClass(): a(1) {}
virtual void do_smth() { std::cout << ++a << std::endl; }
private:
int a;
};
int main() {
BaseClass* ptr = new InheritedClass();
ptr->do_smth();
return 0;
}
In this piece of code, virtual function did alteration of variable belongs to InheritedClass.
I have a question regarding Pure abstract base class. Suppose i have an abstract pure base class with some functions and variables. If i create 2 derived classes from the base, do both the derived classes get their own set of variables?
For example:
#include <iostream>
using namespace std;
class base
{
public:
virtual void display() = 0;
protected:
static input;
static output;
}
class Derived1:public base
{
public:
virtual void display();
void readInput();
}
class Derived2:public base
{
public:
virtual void display();
void readInput();
}
class Derived1:public base
{
virtual void display();
}
int main()
{
Derived1 obj1;
Derived2 obj2;
return 0;
}
So here obj1 and obj2 get 2 sets variables "input" and "output" individually? Or is there only going to be 1 set?
They will have just One set of static variables for all the derived classes. It's very easy to test:
class Base
{
public:
static int k;
};
int Base::k;
class Derived1: public Base
{
};
class Derived2: public Base
{
};
int main(){
Derived1::k = 5;
Derived2::k = 10;
std::cout << Derived1::k << " " << Derived2::k;
}
output: 10 10
The reason is that all static stuff applies to the base class alone (note that they are bound to the class, not to an object, so it's also irrelevant to the number of objects of each class created). Since you have just one base class, it doesn't matter how many derived ones you will have, the set of the variables will still be bound to that single base one.
Although you can easily test this, here's a hint: consider how you define the member:
int base::input;
and now think there's only one base class, and static binds to the class.
static variables are shared between class instances (including derived class instances).
There are two sets of variables; one for obj 1 and one for obj 2.