class Base{
public:
void counter();
....
}
class Dervied: public Base{
public:
....
}
void main()
{
Base *ptr=new Derived;
ptr->counter();
}
To identify that the base class pointer is pointing to derived class and using a derived member function, we make use of "virtual".
Similarly, can we make derived data members "virtual"? (the data member is public)
virtual is a Function specifier...
From standard docs,
7.1.2 Function specifiers
Function-specifiers can be used only in function declarations.
function-specifier:
inline
virtual
explicit
So there is nothing called Virtual data member.
Hope it helps...
No, but you can create a virtual function to return a pointer to what you call virtual data member
No, in C++ there are no virtual data members.
I think not, but you might simulate it using virtual getters and setter perhaps?
To identify that the base class pointer is pointing to derived class and using a derived member function, we make use of "virtual".
That is not correct. We make virtual functions to allow derived classes to provide different implementation from what the base provides. It is not used to identify that the base class pointer is pointing to derived class.
Similarly, can we make derived data members "virtual"? (the data member is public)
Only non static member functions can be virtual. Data members can not be.
Here's a link with some more info on that
No, because that would break encapsulation in a myriad of unexpected ways. Whatever you want to achieve can be done with protected attributes and/or virtual functions.
Besides, virtual functions are a method of dispatch (i.e. selecting which function is going to be called), rather than selecting a memory location corresponding to the member attribute.
A class cannot have a virtual member, see for instance this answer.
However, you can have something similar using pointers, inheritance
and runtime polymorphism.
In the following snippet I define the prototype for a geometrical shape,
that has an area method. The picture class has a member shape* s;
and the methods of that shape pointed by s are used by picture::show().
In this setup it is undesirable to have an instance of picture before
an actual implementation of a shape has been given, hence we force picture to be
abstract by adding a dummy virtual function picture::make_real().
// prototypes
class shape
{
public:
virtual double area() = 0; // to be defined later
};
class picture
{
protected:
shape* s;
virtual void make_real() = 0; // force picture to be abstract
public:
picture(shape* ptr):
s{ptr}
{}
void show()
{
std::cout << s->area() << '\n';
}
};
Next, we actually implement a shape called square and a picture type
square_picture that (literally) has a square shape.
// actual implementation
class square : public shape
{
double len;
public:
square(double l):
len{l}
{}
double area() override
{
return len*len;
}
};
class square_picture : public picture
{
void make_real() override {} // square_picture is not abstract
public:
square_picture(double l):
picture{new square{l}}
{}
~square_picture()
{
delete s;
}
};
The class square_picture can be tested with the following snippet
int main()
{
square_picture A{2.0};
A.show();
//picture B{nullptr}; // error: picture is abstract
return 0;
}
which outputs:
4
I have a base class which uses an array of objects. From that class I derived a new class that uses an array of a different type of object. Both variables have exactly the same name. Virtual member functions were added to both classes to process the arrays. These member functions have no trouble finding the correct variable. The member functions and the variables they use are in a common scope.
The virtual member functions are nearly identical in both classes. Only the type of array changed.
C++ templates could have accomplished the same result.
Maybe you can see the problem in a equivalent way:
class VirtualDataMember{
public:
...
}
class DerviedDataMember: public VirtualDataMember{
public:
...
}
class Base{
public:
VirtualDataMember* dataMember;
void counter();
...
}
Related
Is there any point to making virtual member functions, overridden from a base class private, if those are public in the base class?
struct base {
virtual void a();
};
struct derived : base {
// ...
private:
void a() override;
};
If you are forced to do a 2-phase construction on the implementation class (i.e. have an init() method as well as or instead of a constructor that has to be called (I know, but there are reasons), then this stops you calling any /other/ methods directly on the instance pointer before you pass it back as an interface pointer. Go the extra mile, make the inheritance private, and have your one public init function return the interface pointer!
Another reason is you just don't /need/ to write public: in a final implementation class declaration, so then by default everything is private. But why you would do that and use struct instead of class I don't know. Perhaps this was converted from class at some point due to a style war?
Looking at your design, I see one cannot call derived::a directly, but only through a base interface.
Is there any point? Consider that, once we have a derived instance, we can always up-cast to its base, so given
derived d;
while d.a() wouldn't compile, we can always do
base & b = d;
b.a(); //which actually calls derived::a
In other words: derived::a is not that private, after all, and I would discourage this design, which can be confusing to the user.
Things change if the members private in derived are private in base, as well: this time it is clear that they just cannot be called directly, outside base or derived.
Let's say we have a couple of functions, and want them to be called conditionally, according to a value passed as an argument to a third one:
struct base
{
void dosomething(bool x)
{
if(x)
{
do_this();
}
else
{
do_that();
}
}
private:
virtual void do_this(){}
virtual void do_that(){}
};
Thus a derived class could be like:
struct derived : base
{
private:
void do_this() override { }
void do_that() override { }
};
and no other class can call them, unless it extended base itself:
derived d;
d.dosomething(true); //will call do_this() in derived
d.dosomething(false); //will call do_that() in derived
d.do_that() //won't compile
Yes, if you inherit the base class as private. Otherwise, it is more of a weird explicit-like restriction - user has to has to make an explicit conversion to use the function - it is generally ill advised as few will be able to comprehend the author's intention.
If you want to restrict some functions from base class, make a private/protected inheritance and via using keyword declare which base-methods you want to be protected/public in the derived class.
The same reasoning as for non-virtual methods applies: If only the class itself is supposed to call it make it private.
Consider the template method pattern:
struct base {
void foo() { a() ; b(); }
virtual void a() = 0;
virtual void b() = 0;
};
struct derived : base {
private:
void a() override {}
void b() override {}
};
int main()
{
derived().foo();
}
Perhaps a and b should have been protected, but anyhow the derived can change accesibility and it requires some documentation so that derived knows how it is supposed to implement a and b.
I know that generally it can't, but I was wondering if there was any code out there to allow me to have a function in the super class access a member of the sub class. There are four subclasses each with an int size variable, and for the function I need the size variable. I talked to a teacher about somehow using the friend code but she said that wouldnt work.
You can make a pure virtual function in the base class that returns the size. Then you can implement that function in the derived class which will return the size that is stored in the derived class.
That's what virtual member functions are for:
struct Base {
virtual std::string child_name() = 0;
};
struct Derived1 {
virtual std::string child_name { return "Derived1"; }
};
struct Derived2 {
virtual std::string child_name { return "Derived2"; }
};
Please note that if you specify = 0 in the base class your base class will become "pure virtual" and not instantiable, so if you don't want this behaviour you will have to define a default implementation, that will be used also if a derived class does not define the virtual function.
IMPORTANT: Virtual functions should not be called in the constructor, otherwise you'll receive an exception (if the function is pure virtual) or an undesired behaviour (the default implementation will be called).
I am very confused about base and child class function inheritance.
I have those classes:
#include <point.h>
class Polygon{
public:
Polygon();
virtual ~Polygon();
void addPoint(Point *p);
std::string getType();
Point* getPoint(int index);
int getNumOfPoints();
int getColor();
virtual int area()=0;
private:
std::vector<Point*> _points;
int color;
std::string type = "Polygon";
};
class Rectangle : public Polygon{
public:
Rectangle();
virtual ~Rectangle();
virtual int area();
private:
std::vector<Point*> _points;
int color;
std::string type = "Rectangle";
};
Now, in the main I do this:
Rectangle rect();
rect.getType();
this gives me "Polygon" while I want "Rectangle"
I am quite sure I am confused with inheritance. So, according to how I understand, the base class functions get inherited, but why is it when I run the function it relates to the members of the object base class but not the actual object (Rectangle)?
Will be happy if someone would help!
Much appreciated
What happens is that Rectangle::type is completely unrelated to Polygon::type. It's a separate data member that just happens to have the same name.
One way to achieve the desired effect is by making getType() virtual and overriding it in every derived class:
class Polygon {
public:
virtual std::string getType() = 0;
...
}
class Rectangle: public Polygon {
public:
virtual std::string getType();
...
}
std::string Rectangle::getType() {
return "Rectangle";
}
You have two members named type in an instance of Rectangle. Since private members of Polygon are only accessible to the member functions of that class, it's as if they didn't exist when it comes to declaring members by the same name in Rectangle. It's not even shadowing proper, because in Rectangle, the type member of Polygon would not be accessible. So Polygon::getType returns the type defined in Polygon and not the unrelated one defined in Rectangle.
You have several ways to solve your issue:
Define type as a protected member in Polygon and assign to it in every constructor.
Drop type; declare getType as virtual and override it in every class, returning a constant string.
Use RTTI for what it's good for: finding out the actual class of an object.
Design your program so that you don't need to tell the exact type of an object. This is usually best. Every time you need different behavior for different subclasses of Polygon, write a virtual member function that implements the specific behavior.
You only need the type string in one place - your base class. Because you want it to be accessible in your derived classes but not to your user, make it protected. In each constructor, set it to the appropriate value:
Polygon::Polygon():
type("polygon")
{}
Rectangle::Rectangle()
Polygon()
{
type = "rectangle";
}
Here is a sample of code that annoys me:
class Base {
protected:
virtual void foo() = 0;
};
class Derived : public Base {
private:
Base *b; /* Initialized by constructor, not shown here
Intended to store a pointer on an instance of any derived class of Base */
protected:
virtual void foo() { /* Some implementation */ };
virtual void foo2() {
this->b->foo(); /* Compilator sets an error: 'virtual void Base::foo() is protected' */
}
};
How do you access to the protected overrided function?
Thanks for your help. :o)
Protected members in a base-class are only accessible by the current object.
Thus, you are allowed to call this->foo(), but you are not allowed to call this->b->foo(). This is independent of whether Derived provides an implementation for foo or not.
The reason behind this restriction is that it would otherwise be very easy to circumvent protected access. You just create a class like Derived, and suddenly you also have access to parts of other classes (like OtherDerived) that were supposed to be inaccessible to outsiders.
Normally, you would do it using Base::foo(), which refers to the base class of the current instance.
However, if your code needs to do it the way you're trying to and it's not allowed, then you'll need to either make foo() public or make Derived a friend of Base.
One solution would be to declare a static protected function in Base that redirects the call to the private / protected function (foo in the example).
Lets say:
class Base {
protected:
static void call_foo(Base* base) { base->foo(); }
private:
virtual void foo() = 0;
};
class Derived : public Base {
private:
Base* b;
protected:
virtual void foo(){/* Some implementation */};
virtual void foo2()
{
// b->foo(); // doesn't work
call_foo(b); // works
}
};
This way, we don't break encapsulation because the designer of Base can make an explicit choice to allow all derived classes to call foo on each other, while avoiding to put foo into the public interface or explicitly turning all possible subclasses of Base into friends.
Also, this method works regardless of whether foo is virtual or not, or whether it is private or protected.
Here is a link to a running version of the code above and here another version of the same idea with a little more business logic.
It's a bit fragile, but with the classes you defined here, won't this work?
virtual void foo2() {
reinterpret_cast<Derived *>(this->b)->foo();
}
The reinterpret_cast points at the VTABLE for the base object, and calls it through this members accessor.
You call base functions explicitly with the scope operator (Base::foo()). But in this case, the Base class doesn't define foo (it's pure virtual), so there's actually no function to execute when you say this->b->foo(); since b is a pointer to Base and not Derived.
How do you access to the protected
overrided function?
--- from where?
You can access a protected member only via inheritance (apart from the methods of the same class). Say for example you have a class Derived1 which inherits from Derived, then objects of Derived1 can call foo().
EDIT: MSDN article on protected access specifier.
Suppose I want to have an inheritance hierarchy like this.
class Base
class DerivedOne : public Base
class DerivedTwo : public Base
The base class is not meant to be instantiated, and thus has some pure virtual functions that the derived classes must define, making it an abstract base class.
However, there are some functions that you would like your derived classes to get from your base class. These functions modify private data members that both DerivedOne and DerivedTwo will have.
class Base {
public:
virtual void MustDefine() =0; // Function that derived classes must define
void UseThis(); // Function that derived classes are meant to use
};
However, the UseThis() function is meant to modify private data members. That's where the question comes in. Should I give the Base class dummy private data members? Should I give it protected data members (and thus the derived classes won't declare their own private data members). I know the second approach will decrease encapsulation.
What is the best approach to a situation like this? If a more detailed explanation is needed I'd be happy to provide it.
If those member variables are supposed to exist in all derived classes then you should declare them in the base class. If you are worried about encapsulation, you can make them private and provide protected accessor methods for derived classes.
Another five cents: the good practice is to have abstract interface class which has no other members, but only public pure virtual methods and often public virtual destructor. Then you create base implementation which can also be abstract but can have protected fields, etc.
In you case it would be something like:
class IBlaBla;
class BlaBlaBase : public IBlaBla;
class DerivedOne : public BlaBlaBase
class DerivedTwo : public BlaBlaBase
This allows you to have more flexibility in the future if you decide that Base is no longer good for some specialized task.
Should I give the Base class dummy
private data members?
If you can implement a part of functionality without exposing the details to the derived classes, then do it in base class. If your derived classes would need access to these members, provide setters and getters. However, it is not convenient to have setters available for derived classes because your code becomes tightly coupled.
Encapsulation is sometimes overrated. If your base class and derived classes need to access those members, then they should probably be protected, not private. If it really is something that needs to be encapsulated, then you may want to make them private but provide getters and setters (either make them private to Base, with getters and setters defined there, or private to the derived classes, with pure virtual getters and setters in Base).
It's a bit hard to give you more specific advice without knowing about the actual problem you're trying to solve.
You will have to define Base::UseThis(), in the body of which you will make use of Base's fields (which you will also need to declare in the class definition above). If you only need to access them in UseThis, they can be private. If DerivedOne/Two will need access to them, you should make them protected.
Here is a possible resolution to your dilemna:
class Base {
public:
virtual ~Base() {}
virtual void redefine_me() = 0;
void utility_function();
private:
virtual int get_data_member() = 0;
virtual void set_data_member(int v) = 0;
};
class Derived1 : public Base {
public:
virtual void redefine_me() { do_d1_stuff(); }
private:
int my_private_idaho_;
virtual int get_data_member() { return my_private_idaho_; }
virtual void set_data_member(int v) { my_rpviate_idaho_ = v; }
};
class Derived2 : public Base {
public:
virtual void redefine_me() { do_d2_stuff(); }
private:
int gomer_pyle_;
virtual int get_data_member() { return gomer_pyle_; }
virtual void set_data_member(int v) { gomer_pyle_ = v; }
};
void Base::utility_function()
{
set_data_member(get_data_member() + 1);
}
It's biggest disadvantage is that now access to the private data member is mediated by a virtual function call, which isn't the cheapest thing around. It's also hidden from the optimizer.
This means that if you choose it, you should adopt a pattern where you fetch the private data member into a local variable at the beginning of your utility function and set it from the local variable before you return. Of course some utility functions may call out to functions that require the object state to be updated before they're called, and this pattern would then have to be modified to account for that. But then again, such utility functions are likely not to be able to satisfy the strong exception handling guarantee and should be rethought anyway.
It looks as if you need some interface for client code, and some 'convenient' functionality for implementors of the interface, which they can only use if they follow the rule of calling the useThis function of the convenience layer, which will tweak their private members.
Whenever I gave in to the temptation of putting the convenience functionality in my abstract base class, I regretted it (soon!) afterwards. It takes away a lot of flexibility. The solution proposed by AlexKR makes this situation slightly better.
An alternative way of doing this is providing some convenience class that implementers of the interface can aggregate instead of inheriting it. It can provide a function taking the implementer's members as arguments.
class Interface { public: virtual void f() = 0; };
class Convenience {
public:
void tweakMyMembers( int& member1, float& member2 );
bool somestate;
};
class Implementor : public Interface {
int m1; float m2;
public: Implementor( bool b ): conv( b ) {}
virtual void f() { conv.tweakMyMembers( m1, m2 ); if( m1<m2 ) dothis(); }
};