I'm trying to get the following code to work, but I can't find good-enough documentation on how C++ handles public vs. private inheritance to allow me to do what I want. If someone could explain why I can't access Parent::setSize(int) or Parent::size using private inheritance or Parent::size using public inheritance. To solve this, to I need a getSize() and setSize() method in Parent?
class Parent {
private:
int size;
public:
void setSize(int s);
};
void Parent::setSize(int s) {
size = s;
}
class Child : private Parent {
private:
int c;
public:
void print();
};
void Child::print() {
cout << size << endl;
}
int main() {
Child child;
child.setSize(4);
child.print();
return 0;
}
Change Parent to:
protected: int size;
If you want to access the size member from a derived class, but not from outside the class, then you want protected.
Change Child to:
class Child: public Parent
When you say class Child: private Parent, you are saying it should be a secret that Child is a Parent. Your main code makes it clear that you want Child to be manipulated as a Parent, so it should be public inheritance.
When you use private inheritance, all public and protected members of the base class become private in the derived class. In your example, setSize becomes private in Child, so you can't call it from main.
Also, size is already private in Parent. Once declared private, a member always remains private to the base class regardless of the type of inheritance.
You cannot access private data-members of other classes. If you want to access private attributes of a superclas, you should do so via public or a protected accessors. As for the rest, see #casablanca's answer.
#include <iostream>
using namespace std;
class Parent {
private:
int size;
public:
void setSize(int s);
int fun() //member function from base class to access the protected variable
{
return size;
}
};
void Parent::setSize(int s) {
size = s;
}
class Child : private Parent {
private:
int c;
public:
void print();
using Parent::setSize; //new code line
using Parent::fun; //new code line
};
void Child::print() {
cout << fun() << endl;
}
int main() {
Child child;
child.setSize(4);
child.print();
return 0;
}
Related
I need to make the initializer of a class invisible for the child classes, but visible for the main(). How can I do it? The only way I see is to make it PUBLIC, but it will be inherited to the child classes. Any ideas?
You can make it private and add main as a friend
class A {
private:
A() {}
public:
friend int main(void);
};
int main(void) {
// Your code
}
Making the initializer private (cannot access the initializer even in main), there are many design patterns you can follow for solving your problem. One of the design pattern is Singelton.
The example is given below:
#include <iostream>
using namespace std;
class A{
private:
static A *single_instance;
//private constructor, cannot be inherited
A(){
}
public:
//for getting access in main
static A *getInstance() {
if (single_instance==NULL){
single_instance = new A();
}
return single_instance;
}
void print() {
cout<<"I'm from A";
}
};
//initializing with NULL
A *A ::single_instance=NULL;
class B:A {
//not access to the constructor
//but access to getInstance()
};
int main()
{
//now you can access it in main
A *obj = obj->getInstance();
obj->print();
return 0;
}
Note that, this design makes sure, only one instance can be created from your class.
I'm trying to create an abstract base class that I intend the derive classes to implement a vector<int> member. My problem is if I try to do this:
class BaseClass
{
public:
virtual int GetCount() = 0;
virtual vector<int> ChildData;
}
class CID1 : public BaseClass
{
public:
int GetCount()
{
return 3;
}
//and so on.....
}
I get
'virtual' not permitted on data declarations
'virtual' is not allowed.
What I'm trying to do is:
make my child classes override the vector because they will contain different number of the vector elements
To be able to loop through an array of BaseClass* containing addresses of declared child classes, and the second loop for the data of the vectors.
Am I doing it the right way? Thanks in advance!
Note: I have no prior experience in coding in C++.
Am I doing it the right way?
No.
As the compiler lets you know, you can have virtual member functions but not virtual member variables.
Change the member variables to member functions and make sure you implement them properly in the derived classes.
class BaseClass
{
public:
virtual int GetCount() = 0;
virtual vector<int>& GetChildData() = 0;
}
class CID1 : public BaseClass
{
public:
// virtual keyword is not necessary here
// but helps with understanding code.
virtual int GetCount()
{
return 3;
}
virtual vector<int>& GetChildData()
{
return data;
}
private:
vector<int> data;
}
class Class1 {
Class1() { Class2::counter++;}
}
class Class2: public Class1 {
public:
static int counter;
}
The above is an example of what I am trying to do. I am trying to use a static variable of a subclass in the superclass but that gives me a compiler error since Class1 is initialized first and when the compiler reaches the Class2::counter++; it has not initialized Class2 yet and therefore I get a "Class2 has not been declared" error. How can I fix this? Do I need to change my logic completely?
From a OOP perspective a parent class is not able to access to a child field or property, it should the opposite way a child accessing to a parent field or property. I'm wondering whyeyou need to access tora child field from the parent? If you provide more details what you are trying to achieve the best solution will be provided by someone.
You could just pass a reference to your counter to the base class:
class Class1 {
public:
Class1(int& counter) { ++counter; }
};
class Class2: public Class1 {
public:
static int counter;
Class2() : Class1(counter) { }
};
int Class2::counter = 0;
You may put definition of constructor Class1 after Class2 definition:
class Class1 {
public:
Class1();
};
class Class2: public Class1 {
public:
static int counter;
};
int Class2::counter = 0;
Class1::Class1() { Class2::counter++;}
Live demo
A rule of thumb: base classes don't access child class members or methods.
If the base class needs something from a child class, declare an abstract virtual function in the base class for the child to implement.
Or move the common data members or methods into the base class.
In your case:
class Base
{
virtual void increment_counter(void) = 0;
void my_method(void)
{
increment_counter();
}
};
class Child : public Base
{
int counter;
void increment_counter(void)
{
++counter;
}
};
Simply define the constructor of class Class1 after the definition of Class2.
class Class1 {
public:
Class1();
}
class Class2: public Class1 {
public:
static int counter;
}
Class1::Class1() { Class2::counter++;}
Do not forget to define the static data member of Class2.:)
If you want to get freaky with templates, this sounds a possible use for the curiously recurring template pattern. For example:
template <typename T>
class CRTBase
{
CRTBase() { T::counter++; }
};
class CRTDerived : public CRTBase<CRTDerived>
{
public:
static int counter;
};
int CRTDerived::counter = 0;
Here is my hierarchic of classes.
I have declare following abstract interface class, which have just one function:
class IAuthenticator
{
public:
virtual void CreateJson() = 0;
};
After I have created on more class 'UIData' and inherits it from interface class, in this case:
class UIData : public IAuthenticator
{
protected:
UIData() : mWindowHandle(0)
{ /* Constructor do nothing. **/ }
private:
integer mWindowHandle;
public:
void CreateJson()
{
std::cout<<"UIData::CreateJson\n";
}
};
I have one more class which inherits from UIData
class AuthenticateIn : public UIData
{
private:
string mOrigin;
string mLogoURL;
string mUserID;
public:
void CreateJson()
{
std::cout<<"AuthenticateIn::CreateJson\n";
}
};
Question
In my main function I have write code like this.
int main()
{
AuthenticateIn* ai = new AuthenticateIn();
ai->CreateJson();
}
When I call CreateJson() function I see log "AuthenticateIn::CreateJson". I want to find a way to call CreateJson() and it will be called for all base classes.
I know that I can do that calling this->UIData::CreateJson() from AuthenticateIn class CreateJson function, but is there any other way to do that, some automatic way ? Thanks !!
is there any other way to do that, some automatic way
No, there isn't. You have to call the base class's implementation from the derived class. The compiler won't do this automatically since it doesn't know whether you actually want this.
You have to call the base class function in the derived class sort of like this:
void CreateJson() {
UIData::CreateJSon();
}
etc
No, there is no such way. If you want to call virtual function from base class you should do this directly.
You may not be able to force a call to a virtual base class, but you can use indirection to simulate the behaviour.
typedef int integer;
#include <iostream>
#include <string>
using std::string;
using std::cout;
class IAuthenticator
{
public:
virtual void CreateJson() = 0;
};
class UIData : public IAuthenticator
{
protected:
UIData() : mWindowHandle(0)
{ /* Constructor do nothing. **/ }
private:
integer mWindowHandle;
virtual void CreateJsonPrivate() = 0;
public:
void CreateJson()
{
CreateJsonPrivate();
std::cout<<"UIData::CreateJson\n";
}
};
class AuthenticateIn : public UIData
{
private:
string mOrigin;
string mLogoURL;
string mUserID;
virtual void CreateJsonPrivate()
{
std::cout<<"AuthenticateIn::CreateJson\n";
}
};
int main()
{
AuthenticateIn* ai = new AuthenticateIn();
ai->CreateJson();
}
Output:
AuthenticateIn::CreateJson
UIData::CreateJson
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.