Take a look at this code:
#include <iostream>
using namespace std;
class A
{
private:
int privatefield;
protected:
int protectedfield;
public:
int publicfield;
};
class B: private A
{
private:
A a;
public:
void test()
{
cout << this->publicfield << this->protectedfield << endl;
}
void test2()
{
cout << a.publicfield << a.protectedfield << endl;
}
};
int main()
{
B b;
b.test();
b.test2();
return 0;
}
B has access to this->protectedfield but hasn't to a.protectedfield. Why? Yet B is subclass of A.
B has access only to the protected fields in itself or other objects of type B (or possibly derived from B, if it sees them as B-s).
B does not have access to the protected fields of any other unrelated objects in the same inheritance tree.
An Apple has no right to access the internals of an Orange, even if they are both Fruits.
class Fruit
{
protected: int sweetness;
};
class Apple: public Fruit
{
public: Apple() { this->sweetness = 100; }
};
class Orange: public Fruit
{
public:
void evil_function(Fruit& f)
{
f.sweetness = -100; //doesn't compile!!
}
};
int main()
{
Apple apple;
Orange orange;
orange.evil_function(apple);
}
this->protectedfield:
B enherits of A, this means protectedfield is a property of itself now, so it is able to access it.
a.protectedfield:
a is a member of class B, this member has the protectedfield variable which is protected. B cannot touch it, because protected means only access from A within.
Lets break the whole code in small parts.Copy and paste this two code and try to compile!!!!
#include <iostream>
using namespace std;
class A
{
private:
int privatefield;
protected:
int protectedfield;
public:
int publicfield;
};
int main()
{
A a;
cout<<a.publicfield;
cout<<a.privatefield;/////not possible ! private data can not be seen by an object of that class
cout<<a.protectedfield;////again not possible. protected data is like privete data except it can be inherited by another.If inherited as private then they are private,if as protected then protected and if as public then also protected.
}
Now B inherits class A as private
#include <iostream>
using namespace std;
class A
{
private:
int privatefield;
protected:
int protectedfield;
public:
int publicfield;
};
class B: private A
{
private:
A a;
public:
void test()
{
cout << this->publicfield << this->protectedfield << endl;
}
void test2()
{
cout << a.publicfield << endl;
}
};
int main()
{
/*Now B will have both public and protected data as private!!!!
That means
B now looks like this class
Class B
{
private:
int protectedfield;
int publicfield;
}
As we have discussed private/protected data can not be accessed by object of the class
so you you can not do things like this
B b;
b.protectedfield; or b.publicfield;
*/
B b;
b.privatefield;////Error !!!
b.protectedfield/////error!!!!
}
Thanks!
Related
I have this hierarchy of classes :
B1 B2
\ /
C
How should I make an array of pointers in C++ , in which I can store objects from all the classes?
This is what I tried and is not working:
#include <iostream>
using namespace std;
class MyClass {
public:
void myFunction() {
cout << "Some content in parent class." ;
}
};
class MyOtherClass {
public:
void myOtherFunction() {
cout << "Some content in another class." ;
}
};
class MyChildClass: public MyClass, public MyOtherClass {
};
int main() {
MyChildClass **v=new MyChildClass*[3];
v[1]=new MyClass();
v[2]=new MyOtherClass();
v[1]->myFunction();
return 0;
}
First of all you have to understand, that you can store only pointer to child into pointer to parent and only in that order. Secondly, You may want to use std::variant, so your code will looks like this
#include <iostream>
#include <variant>
using namespace std;
class MyClass {
public:
void myFunction() {
cout << "Some content in parent class." ;
}
};
class MyOtherClass {
public:
void myOtherFunction() {
cout << "Some content in another class." ;
}
};
class MyChildClass: public MyClass, public MyOtherClass {
};
int main() {
std::variant<MyClass*, MyOtherClass*> v[3];
v[1]=new MyClass();
v[2]=new MyOtherClass();
std::get<MyClass*>(v[1])->myFunction();
std::get<MyOtherClass*>(v[2])->myOtherFunction();
return 0;
}
How to make this type of program. How to do that can someone say as soon as possible a simple program will also work like sum of two number with private mode of inheritance.
output need to be look like this
I make this program with public mode of inheritance and I want this program in private mode of inheritance.
I need to use class child : private base1, private base2
#include<iostream>
using namespace std;
class base1
{
public:
int a;
void geta()
{
cout<<"enter value of a: ";
cin>>a;
}
};
class base2
{
public:
int b;
void getb()
{
cout<<"enter value of b: ";
cin>>b;
}
};
class child : public base1, public base2
{
public:
void sum()
{
cout<<"Sum of a and b is: "<<a + b;
}
};
int main()
{
child c;
c.geta();
c.getb();
c.sum();
return 0;
}
Maybe you want this:
...
class child : private base1, private base2
{
public:
void sum()
{
cout << "Sum of a and b is: " << a + b;
}
void getaandb()
{
geta();
getb();
}
};
int main()
{
child c;
c.getaandb();
c.sum();
return 0;
}
How do I make a static method inaccessible from a derived class?
I have an inheritance of classes of the following type Square
from which rectangle and rhombus are derived. Then from the rectangle and rhombus a parallelogram is derived. Then from the parallelogram the trapezoid is derived.
I read all these objects (square, rectangle, rhombus, parallelogram, trapeze) in an object vector, but in the end I want to show how many of each I have read. I want to do this through static functions for each class.
Here is the code:
class A
{
protected:
static int n;
public:
A();
static void numberA()
{
cout << n;
}
};
int A::n;
A::A(){ n++; }
class B:public A
{
protected:
static int n;
public:
B();
static void numberB()
{
cout << n;
}
};
int B::n;
B::B(){ n++; }
int main()
{
A a;
B b;
A::numberA();
cout << endl;
B::numberB();
return 0;
}
output:
2
1
And I want 1, 1 because it is one object of class A and one of class B.
I also tried to make the inheritance private or protected but for nothing.
The problem is that the constructor of the derived class will call the base class constructor too.
An easy fix could be to decrement the count of the base class in the derived constructor.
#include <iostream>
class A
{
protected:
inline static int n_{}; // Since C++17
public:
A()
{
++n_;
};
static int number()
{
return n_;
}
};
class B : public A
{
protected:
inline static int n_{};
public:
B()
{
++n_;
--A::n_; // Decrease base count
}
static int number()
{
return n_;
}
};
class C : public B
{
protected:
inline static int n_{};
public:
C()
{
++n_;
--B::n_; // Decrease base count
}
static int number()
{
return n_;
}
};
class D : public A
{
protected:
inline static int n_{};
public:
D()
{
++n_;
--A::n_; // Decrease base count
}
static int number()
{
return n_;
}
};
int main()
{
A a;
B b;
C c;
D d;
std::cout << A::number() << '\n' << B::number() << '\n'
<< C::number() << '\n' << D::number() << '\n';
return 0;
}
In multiple inheritance,where all the base class contains same function name with different functionality, we can access the protected function from particular base class using "::" scope resolution operator.
However, I tried something else. I created the objects of the base class in inside the child class. And tried calling the function using through object of that particular class.
But I was getting the following compiler error:
"‘void A::func(int&)’ is protected within this context."
Please let me know where did i go wrong.
#include <iostream>
using namespace std;
class A
{
protected:
void func(int & a)
{
a = a * 2;
}
};
class B
{
protected:
void func(int & a)
{
a = a * 3;
}
};
class C
{
protected:
void func(int & a)
{
a = a * 5;
}
};
class D : public A,public B,public C {
public:
int a;
A a_val;
B b_val;
C c_val;
void update_val(int new_val)
{
a = new_val;
a_val.func(a);
b_val.func(a);
c_val.func(a);
}
void check(int);
};
void D::check(int new_val)
{
update_val(new_val);
cout << "Value = " << a << endl;
};
int main()
{
D d;
int new_val;
cin >> new_val;
d.check(new_val);
}
If you want to keep your code with the base classes as having independent functionality and still remaining protected the easiest way to resolve your issue is by slightly changing the name of your protected functions and adding a public function that calls the protected members: See these class declarations for example:
class A {
public:
void func( int& a ) {
func_impl( a );
}
protected:
void func_impl( int& a ) {
a = a * 2;
}
};
class B {
public:
void func( int& b ) {
func_impl( b );
}
protected:
void func_impl( int& b ) {
b = b * 3;
}
};
class C {
public:
void func( int& c ) {
func_impl( c );
}
protected:
void func_impl( int& c ) {
c = c * 5;
}
};
class D : public A, public B, public C {
public:
int a;
A a_val;
B b_val;
C c_val;
void update_val( int val ) {
a = val;
a_val.func( a );
b_val.func( a );
c_val.func( a );
}
void check( int );
};
void D::check( int val ) {
update_val( val );
std::cout << "Value = " << a << std::endl;
}
This provides a nice public interface to call the protected member functions. This also resolves the issue of accessing the protected members. When I run your program and input a value of 5 it returns a result of 150 and works as expected.
This snippet should show you how inheritance works and when you can and can not access protected members:
class DerivedA : public Base {
public:
Base b;
void call_message() {
b.message(); // Protected Member of Base class can not be accessed
}
};
class DerivedB : public Base {
public:
void call_message() {
message(); // This works without problem!
}
};
Just as I did above one way to resolve this is by adding a public interface caller to the protected implementation.
class Base {
public:
void message() {
message_impl();
}
protected:
void message_impl() {
std::cout << "This is a protected member of Base\n";
}
};
Now you can do this:
class DerivedA {
public:
Base b;
void call_message() {
b.message(); // Accessible through public interface.
}
};
When you are in your derived class, it has access to its own ancestor methods. But it doesn't have access to your variables member protected and private methods and variables.
Redesign your code, you are trying things and contorting the other classes design for bad reasons. Francis' code is a good solution, but D doesn't need to inherit from anything.
If you don't want to create another function, you can do something like this:
#include <iostream>
using namespace std;
class A
{
protected:
void func(int & a)
{
a = a * 2;
}
};
class B
{
protected:
void func(int & a)
{
a = a * 3;
}
};
class C
{
protected:
void func(int & a)
{
a = a * 5;
}
};
class D : public A,public B,public C {
public:
int a;
void update_val(int new_val)
{
a = new_val;
this->A::func(a);
this->B::func(a);
this->C::func(a);
}
void check(int);
};
void D::check(int new_val)
{
update_val(new_val);
cout << "Value = " << a << endl;
};
int main()
{
D d;
int new_val;
cin >> new_val;
d.check(new_val);
}
This works because, this refers to the current instance of class D, and it already inherits class A, class B, class C. So you can directly access the protected functions of the respective classes.
Remember: It will not work if you have not inherited the classes.
My scenario is simplified in the following example:
#include <iostream>
#include <vector>
using namespace std;
class C;
class A
{
protected:
C * cPointer;
A();
virtual void updateList() = 0;
void callFunc();
};
class B : public A
{
private:
vector<int> list;
void updateList();
public:
void callFromA();
};
class C
{
friend class A;
friend class B; // I want to get rid off this declaration
private:
int sum;
void set_sum( int val );
public:
static C * getCPointer();
};
A::A()
{
cPointer = C::getCPointer();
}
void A::callFunc()
{
updateList();
}
void B::updateList()
{
list.push_back(2);
list.push_back(4);
int s = 0;
for( unsigned int i=0; i<list.size(); i++ )
{
s += list[i];
}
cPointer->set_sum(s);
}
void B::callFromA()
{
callFunc();
}
void C::set_sum( int val )
{
sum = val;
cout << "Sum at C is: " << sum << endl;
}
C * C::getCPointer()
{
static C cPointer;
return & cPointer;
}
int main( int argc, char ** argv)
{
B b;
b.callFromA();
return 0;
}
This example works fine. But I want to get rid of the "friend class B" declaration in class C and achieving similar functionality. Actually I want to have either of the following:
accessibility of C::set_sum() from B::updateList() which will not be possible without the "friend class B" declaration in class C.
accessibility of B::list in A::callFunc() whereby I can push the logic from B::updateList to A::callFunc() which basically means ability to access a list in the derived class from the base class. In this way, I will be able to access the set_sum() in A::callFunc() due to "friend class A" declaration in class C.
Any idea to achieve this without involving major design changes is desirable!
Thanks!
I'm not sure if I understand all your restrictions, but maybe this works better for you. Basically, you can access B::list from A using a virtual function. I've commented the changes in the code.
#include <iostream>
#include <vector>
using namespace std;
class A;
class C
{
friend class A;
private:
int sum;
void set_sum(int val);
public:
static C * getCPointer();
};
class A
{
protected:
C * cPointer;
A();
virtual int getS() = 0; // virtual function to calculate data from vector in derived class B
virtual void updateList()
{
cPointer->set_sum(getS()); // A is friend of C, so you can access B data from A
}
void callFunc();
};
class B : public A
{
private:
vector<int> list;
void updateList();
int getS() // concrete implementation to access vector data
{
int s = 0;
for (unsigned int i = 0; i < list.size(); i++)
{
s += list[i];
}
return s;
}
public:
void callFromA();
};
A::A()
{
cPointer = C::getCPointer();
}
void A::callFunc()
{
updateList();
}
void B::updateList()
{
list.push_back(2);
list.push_back(4);
A::updateList(); // Call to super implementation
}
void B::callFromA()
{
callFunc();
}
void C::set_sum(int val)
{
sum = val;
cout << "Sum at C is: " << sum << endl;
}
C * C::getCPointer()
{
static C cPointer;
return &cPointer;
}
int main(int argc, char ** argv)
{
B b;
b.callFromA();
return 0;
}
You can not access members of derived classes inside the base class, period. The object at hand might be of the base class, or even of a completely unrelated derived class, with guaranteed "interesting" consecuences. Any design asking for doing so is seriously broken, and needs rethinking.
You can make the member function of the base class which wants to do so virtual, and redefine it in the derived class to do whatever perversion you have in mind. Meanwhile, the chaste member of the base class can just refuse if called, signalling the mistake in a sane way. That way you get a guarantee that nothing too untoward can happen.