A small example to reproduce the error in Visual Studio (Community) 2022:
#include <iostream>
#include <memory>
class Base {
public:
virtual void b();
protected:
std::string Method() {
return "Base::Method";
}
};
class SubA : public Base {
public:
// Prevent compiler from optimizing class away.
int doSomething() {
return 7;
}
};
int main() {
SubA sa;
sa.doSomething();
sa.Method(); // <-- Function is inaccessible.
}
Why is the error? The inheritance is public and I'm calling Method on an object from the SubA class.
The inheritance is public
But the member function is protected. You're accessing the member function from main which is outside of the scope of the class or its decendants, so it has no access to protected member functions.
Related
Consider the following code:
#include <iostream>
using namespace std;
class Parent{
virtual void print() = 0;
};
class Derived : public Parent {};
int main() {
Derived d1;
return 0;
}
My doubt over here is that, print function in the parent class is a private member function, then how does it get inherited in the derived class?
I have this code:
#include <memory>
class SomeInterface {
public:
virtual void VirtualMethod() {}
virtual void PureVirtualMethod() = 0;
};
class SomeInterfaceDependent {
public:
explicit SomeInterfaceDependent(SomeInterface* a) : a_(a) {}
private:
SomeInterface* const a_;
};
class Implementation : protected SomeInterface {
public:
void Init() {
// Ok
auto raw = new SomeInterfaceDependent(this);
// Cannot cast 'Implementation' to its protected base class 'SomeInterface'.
auto shared = std::make_shared<SomeInterfaceDependent>(this);
// Ok
SomeInterface* casted_some_interface = this;
auto shared2 = std::make_shared<SomeInterfaceDependent>(casted_some_interface);
}
protected:
void PureVirtualMethod() override {}
};
int main() {
Implementation i;
i.Init();
return 0;
}
C++ standard 17, compiler GCC.
I get error error: ‘SomeInterface’ is an inaccessible base of ‘Implementation’ when (and):
SomeInterface inherited with protected access modifier.
SomeInterfaceDependent created using std::make_shared.
SomeInterface casted implicitly.
Why? Is it the std::make_shared bug?
Is it the std::make_shared bug?
No.
Why?
std::make_shared is not a friend of Implementation, and therefore it doesn't have access to its non-public bases, and therefore it cannot implicitly convert the pointer.
protected inheritance is NOT public to external classes.
Because of this, the compiler does not have visibility to see that Implementation inherits from SomeInterface, and will say its cannot do the cast.
Here the object of derived class d cannot call the protected member function of the class base.
#include <iostream>
using namespace std;
class base
{
protected:
int i,j;
void setij(int a,int b)
{
i=a;
j=b;
}
void showij()
{
cout<<i<<" "<<j<<endl;
}
};
class derived : protected base
{
int k;
public:
void show()
{
base b;
b.setij(10,20);
b.showij();
}
};
int main()
{
base b;
derived d;
d.setij(3,4);
d.showij();
d.show();
return 0;
}
I expect the output is 10 20, but the compiler is showing error.
You used protected inheritance. The problem is not that the derived cannot access protected methods of the base, but the problem is that you cannot access base methods from outside of derived.
If you don't know what protected inheritance means you can read eg here Difference between private, public, and protected inheritance
I doubt you wanted to use protected inheritance here (why would you?). Change it to public inheritance and your code should be fine:
class derived : public base ...
PS: The error message should have told you what is the actual problem (albeit in a cryptic way). Please next time include it in the question. If you cannot understand it, probably others will.
There is a lot wrong with this code. Even if you change the inheritance of class derived from protected to public, the following problems still exist:
In class derived, statements b.setij(10,20); and b.showij(); will still generate compiler errors. See Why can't a derived class call protected member function in this code? for a good explanation. The short explanation: a method can only call a protected method in a base class on the object for which it was originally invoked.
Function main will not be able to call d.setij(3,4); or d.showij(); because these are protected methods in class base.
This should run:
#include <iostream>
using namespace std;
class base
{
protected:
int i,j;
void setij(int a,int b)
{
i=a;
j=b;
}
void showij()
{
cout<<i<<" "<<j<<endl;
}
};
class derived : public base
{
int k;
public:
void show()
{
this->setij(10,20);
this->showij();
}
};
int main()
{
derived d;
d.show();
return 0;
}
I have a base class and the derived class. I need to access the protected member of the base class in the derived class. However, Eclipse does not allow me to access the data member as if it were a member of a derived class without caring that it was inherited. How do I do that?
class BaseClass {
protected:
static int a;
int b;
}
class DerivedClass: public BaseClass {
void SomeMethod {
a=10; // cannot resolve symbol
b=10; // cannot resolve symbol
BaseClass::a=10; //does not complain
BaseClass::b=10; //does not complain
}
}
I couldn't completely understand your question, but fixing the syntax errors, the following should work:
class BaseClass {
protected:
static int a;
int b;
}; // <-- Missing semicolon
int BaseClass::a = 0; // Define static member
class DerivedClass: public BaseClass {
void SomeMethod() { // <-- Missing ()
a=10;
b=10;
}
};// <-- Missing semicolon
I have defined base class and derived class in separate namepsaces(This is a requirement as several classes can be derived from a single base class and based on behaviour of derived classes they are to be place din separate namespaces.)
Base.h
namespace global
{
{
class Base
{
public:
Base();
virtual ~Base();
virtual int someFunc(int arg1);
}
}
Derived.h
namespace global
{
namespace derived
{
class Derived: public Base()
{
public:
Derived();
~Derived();
}
}
}
Derived.cpp
namespace global
{
namespace derived
{
Derived::Derived() {}
Derived::~Derived() {}
int Derived::someFunc(int arg1)
{
//some code here
}
}
}
When I try to compile this code, I get the error:
no 'int global::derived::Derived::someFunc(int arg1)' member function declared in class global::derived::Derived.
So, do I need to declare someFunc in Derived again?
like:
namespace global
{
namespace derived
{
class Derived: public Base()
{
public:
Derived();
~Derived();
int someFunc(arg1 int);
}
}
}
Now, if there is some Function in a totally separate namespace, that accepts base class reference, how can I pass it derived class reference?
tryFunc(Base &b);
Derived d;
tryFunc(d);
Is this correct?
Thanks.
You basically figured out everything already, you got to declare someFunc in the class body of the derived class.
Also the way of passing to tryFunc(Base &b)is correct