Just wanted some clarification.
Should abstract base classes never have private members? For example
class abc{
public:
virtual void foo()=0;
private:
int myInt;
}
you can never access myInt since you cannot create an instance of abc and it will not be in a derived class since its private.
Is there any situation where you would use private members in abstract base classes or is this just wrong?
In C++ you can have an abstract class that has non pure virtual methods. In that case, and depending on the design it can make sense to have private members:
class base {
std::string name;
public:
base( std::string const & n ) : name(n) {}
std::string const & getName() const { return name; }
virtual void foo() = 0;
};
That code ensures that every object that derives from base has a name, that is set during construction and never changes during the lifetime of the object.
EDIT: For completion after Charles Bailey reminded me of it in his answer
You can also define pure-virtual functions, and in that case, private attributes could also make sense:
// with the above definition of base
void base::foo() {
std::cout << "My name is " << name << std::endl;
}
It's normally not advisable to have data members in an abstract class but there is nothing technically wrong with your example. In the implementation of foo, which is publicly accessible you can use myInt for whatever purposes you like.
For example:
class abc{
public:
virtual void foo()=0;
private:
int myInt;
};
class xyz : public abc
{
virtual void foo();
};
#include <iostream>
#include <ostream>
void xyz::foo()
{
std::cout << "xyz::foo()\n";
abc::foo();
}
void abc::foo()
{
std::cout << "abc::foo(): " << myInt++ << '\n';
}
#include <memory>
int main()
{
std::auto_ptr<abc> p( new xyz() ); // value-initialization important
p->foo();
p->foo();
}
Output:
xyz::foo()
abc::foo(): 0
xyz::foo()
abc::foo(): 1
Not all methods in an abstract base class must be pure virtual. You might have some methods which are useful to all subclasses. Thus if you have some functionality in the base class which is modifying internal state you would have private members for those.
If you use the Template Method design pattern (to implement the open/closed principle), it is quite common to have private members of an abstract base class.
As it stands, your example makes no sense.
However, abstract base classes are allowed to have member function definitions, which in turn are allowed to access private member data in the base class.
You can access Private Members through this shortcut way
Code is in PHP
abstract class myclass1
{
private $var="46789";
public function test($valuetoset)
{
echo $this->var = $valuetoset;
}
}
class myclass2 extends myclass1
{
}
$obj = new myclass2();
$obj->test(78);
Related
When designing an interface, someone recommended to use the non-virtual interface pattern. Can someone briefly outline what the benefits of this pattern are?
The essence of the non-virtual interface pattern is that you have private virtual functions, which are called by public non-virtual functions (the non-virtual interface).
The advantage of this is that the base class has more control over its behaviour than it would if derived classes were able to override any part of its interface. In other words, the base class (the interface) can provide more guarantees about the functionality it provides.
As a simple example, consider the good old animal class with a couple of typical derived classes:
class Animal
{
public:
virtual void speak() const = 0;
};
class Dog : public Animal
{
public:
void speak() const { std::cout << "Woof!" << std::endl; }
};
class Cat : public Animal
{
public:
void speak() const { std::cout << "Meow!" << std::endl; }
};
This uses the usual public virtual interface that we're used to, but it has a couple of problems:
Each derived animal is repeating code -- the only part that changes is the string, yet each derived class needs the whole std::cout << ... << std::endl; boilerplate code.
The base class can't make guarantees about what speak() does. A derived class may forget the new line, or write it to cerr or anything for that matter.
To fix this, you can use a non-virtual interface that is supplemented by a private virtual function that allows polymorphic behaviour:
class Animal
{
public:
void speak() const { std::cout << getSound() << std::endl; }
private:
virtual std::string getSound() const = 0;
};
class Dog : public Animal
{
private:
std::string getSound() const { return "Woof!"; }
};
class Cat : public Animal
{
private:
std::string getSound() const { return "Meow!"; }
};
Now the base class can guarantee that it will write out to std::cout and end with a new line. It also makes maintenance easier as derived classes don't need to repeat that code.
Herb Sutter wrote a good article on non-virtual interfaces that I would recommend checking out.
Here is a wiki article it a bit more in details with some examples. The essence is that you can ensure important conditions (like obtaining and releasing locks) in a central place in your base class while still allowing to derive from it to provide different implementations by using private or protected virtual functions.
Users of any class of the class hierarchy will always call the public interface which dispatches the calls to the not externally visible implementations.
I'm sure I'm not the first one to ask this question, but I can not find any answer for it.
The thing I want is a base class from which multiple classes are inherited. The inherited classes all have some functions (with implementation) and variables in common and have some variables and functions (different functions for every derived class) of there own. The common members I would like to combine in the base class. The thing is the base class should really just be a base class and I don't want any instances to be made of the base class. How should I do this?
If the above description is not clear, maybe this makes it more clear: let's say I want a base class mammals and derived class such as human, ape, blue whale, etc. I want to create instances of the human, ape, blue whale, etc. but not of mammals.
I have read somewhere you could put the constructor as private, but I need a public constructor of the derived classes
Making the base class abstract is your solution.
If you don't want to make any base class method pure virtual then you can make the destructor pure virtual
#include <iostream>
using namespace std;
class IMammal //I for Interface
{
public:
virtual ~IMammal() = 0; //Makes the class abstract, Pure virtual destructor
};
IMammal::~IMammal() //Its necessary or ld will complain
{
cout << "In ~IMammal" << endl;
}
class Ape : IMammal
{
};
int main()
{
// IMammal m; // error: cannot declare variable ‘m’ to be of abstract type ‘IMammal’
Ape a;
}
Since every method is implemented in the base class, using a protected constructor will allow you to add extra member variables to the derived class without being able to construct the base. To make it even more obvious, I'd probably put the base class in a different namespace, so the caller gets a strong hint that they shouldn't even try to create one.
namespace detail
{
class Mammal
{
public:
void layEggs() { /*implementation*/ }
protected:
//Stop anyone creating a Mammal
//Can still be accessed by derived classes,
//and anyone that Mammal has declared a friend
Mammal(int age) : age_(age);
int age_;
};
}
class Dog : public detail::Mammal
{
public:
//Dog is still allowed to access Mammal constructor
Dog(int age, const std::string& name) :
Mammal(age), name_(name)
{}
protected:
std::string name_;
};
Edit: I originally answered without understand that every method was implemented in the base class
You can do this by making the class an abstract class. You do this by creating at least one function a pure virtual function.
class Mammal
{
public:
void layEggs()
{
//implemented in base
}
virtual std:string speak() = 0 //pure virtual, so class cannot be instantiated
};
class Dog : public Mammal
{
public:
virtual std::string speak()
{
return "woof";
}
};
Because Mammal contains a pure virtual function, a variable cannot be created from it. However, Dog has implemented all of the functions, so a variable can be created.
Mammal m; //will result in compiler error, because what would m.speak() do?
Dog d; //is allowed, because we know what d.speak() should do
I think the suggestion of Alan Birtles might indeed work. Check this question What are practical uses of a protected constructor?
All functions I would have in the base class have an implementation in the base class. Otherwise using a virtual function would indeed be an option as well. I checked this website https://www.geeksforgeeks.org/pure-virtual-functions-and-abstract-classes/ maybe this is useful for others.
I got a Question in my Exam which was this:
Function Overriding means the functions have the same prototype but
differ in their body
Justify the Statement with the help of an Example.
Now I quoted this code snippet as Example :
#include<iostream>
using namespace std;
class A {
public: virtual void print() {
cout << "I am Base Class's print Function" << endl;
}
};
class B: public A {
public: void print() {
cout << "I am Derived's Class print function" << endl;
}
};
Here I have made two classes, Class A and Class B and Class B is inheriting Class A. Now, by definition of Method Overriding, we mean that the Function which gets created in the Base Class gets overridden in the Derived Class.
I made the Function in the Base Class as a Virtual Function.
Now, my main() file:
int main() {
A * a1;
B b1;
a1 = & b1;
a1 - > print();
}
Now, I want to ask that is my above code snippet example for above question is right or not. I have performed Function Overriding at run time. In my main file, the Base Class Object is a Pointer that is having the Address of the Derived Class. When I will call print() function using a1, it will execute the print() function of the Derived Class.
So isn't my example justified? Am I right or not?
You could use the classical Cat vs Dog example where both classes inherit from a common base class, i.e. Animal. The common base class can then have a pure virtual function that is then overridden with a differing implementation (method body) in each subclass.
#include <iostream>
class Animal
{
public:
virtual ~Animal() = default;
virtual void MakeSound() const = 0;
};
class Dog : public Animal
{
public:
virtual void MakeSound() const override;
};
class Cat : public Animal
{
public:
virtual void MakeSound() const override;
};
void Dog::MakeSound() const
{
std::cout << "Woof!" << std::endl;
}
void Cat::MakeSound() const
{
std::cout << "Meow!" << std::endl;
}
int main()
{
const Dog dog{};
const Cat cat{};
const Animal& firstAnimal{dog};
const Animal& secondAnimal{cat};
/*
* These functions have the same prototype, void MakeSound(),
* but differ in their implementation.
*/
firstAnimal.MakeSound();
secondAnimal.MakeSound();
return 0;
}
If you teacher expected this as answer and considers your example as wrong then I would argue that they teach you overriding the wrong way.
From cppreference:
Virtual functions are member functions whose behavior can be overridden in derived classes.
Of course this does not strictly imply the reverse statement: "functions that can be overriden are virtual". But if this wasnt true, the quoted sentence would make little sense.
Non-virtual methods are not really meant to be overriden. From the C++ FAQ:
Should a derived class redefine (“override”) a member function that is non-virtual in a base class?
It’s legal, but it ain’t moral. [...]
Note that they put "override" in quotes, because strictly speaking it is not overriding but merely redefining.
Further, you can read on cpprefernce about the override specifier (emphasize mine):
In a member function declaration or definition, override ensures that the function is virtual and is overriding a virtual function from a base class. The program is ill-formed (a compile-time error is generated) if this is not true.
TL;DR If I had to judge I would consider this as a misleading bad example for overriding, while your code seems fine. It could benefit from using override and A should have a virtual destructor, but thats details.
I'm using c++ and i have no idea on how can i access the variables in my base class using the derived class.
I need to get the values in the base class and do an operation in the derived class, since all the functions in the base class contains arguments, when I call the function,
ex:
Baseclass.getvalue();
i can't put any arguments since it is not defined.
I already did the constructor parts like
class derivedclass:baseclass
{
//insert functions here.
};
derivedclass::derivedclass()
:baseclass()
{
//insert initialization here
}
but i still can't access the values. help? do i need to use virtual? if yes, how?
*this is a user-defined program
simply access the (public or protected) values as if they were part of your derived class.
class baseclass {
protected:
int m_value;
public:
baseclass();
virtual int getvalue();
};
class derivedclass : public baseclass {
void dosomething(void) {
// whoa: `m_value` is part of `baseclass`, and we can simply access it here!
std::cout << "value: " << m_value << std::endl;
// we can also use `getvalue()`
std::cout << "getvalue(): " << getvalue() << std::endl;
}
};
In this case, the inheritance is private, so the base subobject and its members are only accessible within the derived class and its friends. By default, members and base classes are private if the class definition is introduced with the class keyword, and public with the struct keyword. If you want to access them from outside, then you'll need public inheritance:
class derivedclass : public baseclass {/*...*/};
or
struct derivedclass : baseclass {/*...*/};
If the derived class doesn't hide the member by declaring a member with the same name, you can access it as if it were a member of the derived class. (If the inheritance is protected or private, then it will be protected or private within the derived class, and so may not be accessible).
If it is hidden, and you specifically want the base-class version, then you'll need to qualify the member name:
Derived.baseclass::getvalue()
but if this is the case, then there's something funky going on and the class interfaces probably need rethinking.
Say B and C are derived from A. I want to be able to test whether any two instances of classes derived from A are instances of the same class, that is, whether A* foo and A* bar both point to B instances, without using RTTI. My current solution is something like this:
class A {
protected:
typedef uintptr_t Code;
virtual Code code() const = 0;
}; // class A
class B : public A {
protected:
virtual Code code() const { return Code(&identity); }
private:
static int identity;
}; // class B
class C : public A {
protected:
virtual Code code() const { return Code(&identity); }
private:
static int identity;
}; // class C
Using this method, operator== can simply test first.code() == second.code(). I'd like to remove the literal identity from the derived classes and have the code found automatically by A, so that not all of the derived classes have to repeat this idiom. Again, I would strongly prefer not to use RTTI. Is there any way to do this?
Note: I have seen recent questions [1] and [2], and this is not a duplicate. Those posters want to test the contents of their derived classes; I merely want to test the identities.
You should just use RTTI instead of reinventing the wheel.
If you insist on not using RTTI, you could use CRTP and a function-local static variable to avoid having to write the function to every derived class. Adapt from this example code I wrote for Wikipedia: http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern#Polymorphic_copy_construction
Another alternative is reading the vtable pointer (via this and pointer arithmetics), but that would depend on both the compiler and the platform, so it is not portable.
Your idea is on the right track; maybe you can eliminate some boilerplate with a template:
class TypeTagged {
public:
virtual Code code() const = 0;
}
template <class T>
class TypeTaggedImpl: public virtual TypeTagged {
public:
virtual Code code() const { return Code(&id); }
private:
static int id;
}
Then your client classes just need to be declared like this:
class A: public TypeTaggedImpl<A> { ... }
class B: public A, public TypeTaggedImpl<B> { ... }
The different instantiations of TypeTagged mean that the types have different id fields and hence different IDs; the virtual base type means that the code for the most derived type gets returned.
You can have the Base class to take id as a constructor parameter and implement the identity() function in base class itself. Then there is no need to repeat the code in derived classes. In the derived class constructor, you can do something like derived::derived(): base(0) Sample Code:
class A
{
public:
A(int n) : m_id(n)
{
}
virtual ~A(){}
virtual int id() const
{
return m_id;
}
private:
int m_id;
};
class B : public A
{
public:
B() : A(0)
{
}
};
you can use the both macro __FILE__ __LINE__ as your code
this will avoid the collision problem
you can map this values to an int