Can a superclass function access a subclass data-member - c++

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).

Related

Private overriden virtual functions in derived class

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.

How to declare an "unknown" derived class as base class as a member and allow the derived version of member function to be called?

I am currently trying to set a member of a class (myClass) to be some derived classes (Derived1, Derived2,...) of a Base class. Since the class don't know which derived class it is, the member type is set to Base class, it is only set to the derived class when constructed.
The derived classes all have a common member function which is implemented differently (Base class has a virtual version). However, when the this function is called from myClass, it always call the Base class version rather than the derived classes.
class Base
{
public:
Base(){}
virtual void who() { cout << "this is Base"; }
}
class Derived1 : public Base
{
public:
Derived1() : Base() {}
void who() { cout << "this is Derived1"; }
}
class myClass
{
private:
Base unknownDerived;
public:
myClass(const Base& inputDerived) { unknownDerived = inputDerived; }
void whosthere() { unknownDerived.who(); }
}
The output above is "this is Base", the Base class version is called instead.
Is there a way to include a member without specifying the actual derived class it is, but be able to call its specific function ( who() )?
thanks a lot!
When you declare Base as a member, Base is what you actually get. Even if you assign a Derived type to it, you experience what's called "slicing", where only the Base part of the derived object is copied, and your object is still a Base.
In C++, polymorphism only works through pointers and through references.
To make a real member object (not an indirection to the object) in myClass, you will need to make myClass have a template parameter, and you can decide at compile time what type it will be. Otherwise, you must use pointers and/or references.
Now you have to be clear about memory ownership, and proper cleanup. You may make the caller transfer the ownership of the object (by taking a unique_ptr) or you might insist that Base has a virtual clone() function to create a deep copy of the object. Further, you most likely will need a virtual destructor in your base class as well.

How to access protected method in base class from derived class?

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.

can a class have virtual data members?

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();
...
}

Virtual/pure virtual explained

What exactly does it mean if a function is defined as virtual and is that the same as pure virtual?
From Wikipedia's Virtual function
...
In object-oriented programming, in languages such as C++, and Object Pascal, a virtual function or virtual method is an inheritable and overridable function or method for which dynamic dispatch is facilitated. This concept is an important part of the (runtime) polymorphism portion of object-oriented programming (OOP). In short, a virtual function defines a target function to be executed, but the target might not be known at compile time.
Unlike a non-virtual function, when a virtual function is overridden the most-derived version is used at all levels of the class hierarchy, rather than just the level at which it was created. Therefore if one method of the base class calls a virtual method, the version defined in the derived class will be used instead of the version defined in the base class.
This is in contrast to non-virtual functions, which can still be overridden in a derived class, but the "new" version will only be used by the derived class and below, but will not change the functionality of the base class at all.
whereas..
A pure virtual function or pure virtual method is a virtual function that is required to be implemented by a derived class if the derived class is not abstract.
When a pure virtual method exists, the class is "abstract" and can not be instantiated on its own. Instead, a derived class that implements the pure-virtual method(s) must be used. A pure-virtual isn't defined in the base-class at all, so a derived class must define it, or that derived class is also abstract, and can not be instantiated. Only a class that has no abstract methods can be instantiated.
A virtual provides a way to override the functionality of the base class, and a pure-virtual requires it.
I'd like to comment on Wikipedia's definition of virtual, as repeated by several here. [At the time this answer was written,] Wikipedia defined a virtual method as one that can be overridden in subclasses. [Fortunately, Wikipedia has been edited since, and it now explains this correctly.] That is incorrect: any method, not just virtual ones, can be overridden in subclasses. What virtual does is to give you polymorphism, that is, the ability to select at run-time the most-derived override of a method.
Consider the following code:
#include <iostream>
using namespace std;
class Base {
public:
void NonVirtual() {
cout << "Base NonVirtual called.\n";
}
virtual void Virtual() {
cout << "Base Virtual called.\n";
}
};
class Derived : public Base {
public:
void NonVirtual() {
cout << "Derived NonVirtual called.\n";
}
void Virtual() {
cout << "Derived Virtual called.\n";
}
};
int main() {
Base* bBase = new Base();
Base* bDerived = new Derived();
bBase->NonVirtual();
bBase->Virtual();
bDerived->NonVirtual();
bDerived->Virtual();
}
What is the output of this program?
Base NonVirtual called.
Base Virtual called.
Base NonVirtual called.
Derived Virtual called.
Derived overrides every method of Base: not just the virtual one, but also the non-virtual.
We see that when you have a Base-pointer-to-Derived (bDerived), calling NonVirtual calls the Base class implementation. This is resolved at compile-time: the compiler sees that bDerived is a Base*, that NonVirtual is not virtual, so it does the resolution on class Base.
However, calling Virtual calls the Derived class implementation. Because of the keyword virtual, the selection of the method happens at run-time, not compile-time. What happens here at compile-time is that the compiler sees that this is a Base*, and that it's calling a virtual method, so it insert a call to the vtable instead of class Base. This vtable is instantiated at run-time, hence the run-time resolution to the most-derived override.
I hope this wasn't too confusing. In short, any method can be overridden, but only virtual methods give you polymorphism, that is, run-time selection of the most derived override. In practice, however, overriding a non-virtual method is considered bad practice and rarely used, so many people (including whoever wrote that Wikipedia article) think that only virtual methods can be overridden.
The virtual keyword gives C++ its' ability to support polymorphism. When you have a pointer to an object of some class such as:
class Animal
{
public:
virtual int GetNumberOfLegs() = 0;
};
class Duck : public Animal
{
public:
int GetNumberOfLegs() { return 2; }
};
class Horse : public Animal
{
public:
int GetNumberOfLegs() { return 4; }
};
void SomeFunction(Animal * pAnimal)
{
cout << pAnimal->GetNumberOfLegs();
}
In this (silly) example, the GetNumberOfLegs() function returns the appropriate number based on the class of the object that it is called for.
Now, consider the function 'SomeFunction'. It doesn't care what type of animal object is passed to it, as long as it is derived from Animal. The compiler will automagically cast any Animal-derived class to a Animal as it is a base class.
If we do this:
Duck d;
SomeFunction(&d);
it'd output '2'. If we do this:
Horse h;
SomeFunction(&h);
it'd output '4'. We can't do this:
Animal a;
SomeFunction(&a);
because it won't compile due to the GetNumberOfLegs() virtual function being pure, which means it must be implemented by deriving classes (subclasses).
Pure Virtual Functions are mostly used to define:
a) abstract classes
These are base classes where you have to derive from them and then implement the pure virtual functions.
b) interfaces
These are 'empty' classes where all functions are pure virtual and hence you have to derive and then implement all of the functions.
In a C++ class, virtual is the keyword which designates that, a method can be overridden (i.e. implemented by) a subclass. For example:
class Shape
{
public:
Shape();
virtual ~Shape();
std::string getName() // not overridable
{
return m_name;
}
void setName( const std::string& name ) // not overridable
{
m_name = name;
}
protected:
virtual void initShape() // overridable
{
setName("Generic Shape");
}
private:
std::string m_name;
};
In this case a subclass can override the the initShape function to do some specialized work:
class Square : public Shape
{
public:
Square();
virtual ~Square();
protected:
virtual void initShape() // override the Shape::initShape function
{
setName("Square");
}
}
The term pure virtual refers to virtual functions that need to be implemented by a subclass and have not been implemented by the base class. You designate a method as pure virtual by using the virtual keyword and adding a =0 at the end of the method declaration.
So, if you wanted to make Shape::initShape pure virtual you would do the following:
class Shape
{
...
virtual void initShape() = 0; // pure virtual method
...
};
By adding a pure virtual method to your class you make the class an abstract base class
which is very handy for separating interfaces from implementation.
"Virtual" means that the method may be overridden in subclasses, but has an directly-callable implementation in the base class. "Pure virtual" means it is a virtual method with no directly-callable implementation. Such a method must be overridden at least once in the inheritance hierarchy -- if a class has any unimplemented virtual methods, objects of that class cannot be constructed and compilation will fail.
#quark points out that pure-virtual methods can have an implementation, but as pure-virtual methods must be overridden, the default implementation can't be directly called. Here is an example of a pure-virtual method with a default:
#include <cstdio>
class A {
public:
virtual void Hello() = 0;
};
void A::Hello() {
printf("A::Hello\n");
}
class B : public A {
public:
void Hello() {
printf("B::Hello\n");
A::Hello();
}
};
int main() {
/* Prints:
B::Hello
A::Hello
*/
B b;
b.Hello();
return 0;
}
According to comments, whether or not compilation will fail is compiler-specific. In GCC 4.3.3 at least, it won't compile:
class A {
public:
virtual void Hello() = 0;
};
int main()
{
A a;
return 0;
}
Output:
$ g++ -c virt.cpp
virt.cpp: In function ‘int main()’:
virt.cpp:8: error: cannot declare variable ‘a’ to be of abstract type ‘A’
virt.cpp:1: note: because the following virtual functions are pure within ‘A’:
virt.cpp:3: note: virtual void A::Hello()
A virtual function is a member function that is declared in a base class and that is redefined by derived class. Virtual function are hierarchical in order of inheritance.
When a derived class does not override a virtual function, the function defined within its base class is used.
A pure virtual function is one that contains no definition relative to the base class.
It has no implementation in the base class. Any derived class must override this function.
How does the virtual keyword work?
Assume that Man is a base class, Indian is derived from man.
Class Man
{
public:
virtual void do_work()
{}
}
Class Indian : public Man
{
public:
void do_work()
{}
}
Declaring do_work() as virtual simply means: which do_work() to call will be determined ONLY at run-time.
Suppose I do,
Man *man;
man = new Indian();
man->do_work(); // Indian's do work is only called.
If virtual is not used, the same is statically determined or statically bound by the compiler, depending on what object is calling. So if an object of Man calls do_work(), Man's do_work() is called EVEN THOUGH IT POINTS TO AN INDIAN OBJECT
I believe that the top voted answer is misleading - Any method whether or not virtual can have an overridden implementation in the derived class. With specific reference to C++ the correct difference is run-time (when virtual is used) binding and compile-time (when virtual is not used but a method is overridden and a base pointer is pointed at a derived object) binding of associated functions.
There seems to be another misleading comment that says,
"Justin, 'pure virtual' is just a term (not a keyword, see my answer
below) used to mean "this function cannot be implemented by the base
class."
THIS IS WRONG!
Purely virtual functions can also have a body AND CAN BE IMPLEMENTED! The truth is that an abstract class' pure virtual function can be called statically! Two very good authors are Bjarne Stroustrup and Stan Lippman.... because they wrote the language.
Simula, C++, and C#, which use static method binding by default, the programmer can specify that particular methods should use dynamic binding by labeling them as virtual.
Dynamic method binding is central to object-oriented programming.
Object oriented programming requires three fundamental concepts: encapsulation, inheritance, and dynamic method binding.
Encapsulation allows the implementation details of an
abstraction to be hidden behind a
simple interface.
Inheritance allows a new abstraction to be defined as an
extension or refinement of some
existing abstraction, obtaining some
or all of its characteristics
automatically.
Dynamic method binding allows the new abstraction to display its new
behavior even when used in a context
that expects the old abstraction.
Virtual methods CAN be overridden by deriving classes, but need an implementation in the base class (the one that will be overridden)
Pure virtual methods have no implementation the base class. They need to be defined by derived classes. (So technically overridden is not the right term, because there's nothing to override).
Virtual corresponds to the default java behaviour, when the derived class overrides a method of the base class.
Pure Virtual methods correspond to the behaviour of abstract methods within abstract classes. And a class that only contains pure virtual methods and constants would be the cpp-pendant to an Interface.
Pure Virtual Function
try this code
#include <iostream>
using namespace std;
class aClassWithPureVirtualFunction
{
public:
virtual void sayHellow()=0;
};
class anotherClass:aClassWithPureVirtualFunction
{
public:
void sayHellow()
{
cout<<"hellow World";
}
};
int main()
{
//aClassWithPureVirtualFunction virtualObject;
/*
This not possible to create object of a class that contain pure virtual function
*/
anotherClass object;
object.sayHellow();
}
In class anotherClass remove the function sayHellow and run the code. you will get error!Because when a class contain a pure virtual function, no object can be created from that class and it is inherited then its derived class must implement that function.
Virtual function
try another code
#include <iostream>
using namespace std;
class aClassWithPureVirtualFunction
{
public:
virtual void sayHellow()
{
cout<<"from base\n";
}
};
class anotherClass:public aClassWithPureVirtualFunction
{
public:
void sayHellow()
{
cout<<"from derived \n";
}
};
int main()
{
aClassWithPureVirtualFunction *baseObject=new aClassWithPureVirtualFunction;
baseObject->sayHellow();///call base one
baseObject=new anotherClass;
baseObject->sayHellow();////call the derived one!
}
Here the sayHellow function is marked as virtual in base class.It say the compiler that try searching the function in derived class and implement the function.If not found then execute the base one.Thanks
"A virtual function or virtual method is a function or method whose behavior can be overridden within an inheriting class by a function with the same signature" - wikipedia
This is not a good explanation for virtual functions. Because, even if a member is not virtual, inheriting classes can override it. You can try and see it yourself.
The difference shows itself when a function take a base class as a parameter. When you give an inheriting class as the input, that function uses the base class implementation of the overriden function. However, if that function is virtual, it uses the one that is implemented in the deriving class.
Virtual functions must have a definition in base class and also in derived class but not necessary, for example ToString() or toString() function is a Virtual so you can provide your own implementation by overriding it in user-defined class(es).
Virtual functions are declared and defined in normal class.
Pure virtual function must be declared ending with "= 0" and it can only be declared in abstract class.
An abstract class having a pure virtual function(s) cannot have a definition(s) of that pure virtual functions, so it implies that implementation must be provided in class(es) that derived from that abstract class.