I have 3 classes:
Class A
Class B
Class C
In class A, 2 methods are declared, one is void, the second is virtual void.
The virtual void Method2 is defined in class B.
In class C, I call Method1 and Method2;
As a result, I get the following error:
error: 'void Base::A::Method1()' is inaccessible within this context
error: 'Base::A' is not an accessible base of ‘Main::B’
namespace Base {
class A {
public:
A() {}
void Method1() {std::cout << "it is method1\n";}
virtual void Method2() =0;
}; // class A
} // namespace Base
namespace Main {
class B : A {
public:
B() {}
void Method2() {}
}; // class B
class C {
public:
C() {}
void Handle() {
b->Method1(); // it is good
b->Method2(); // this is error
}
private:
std::unique_ptr<B> b;
}; // class C
} // namespace Main
What could be the problem?
You made two errors in one instruction, the declaration of class B. In the context of
namespace Base {
class A {...}
}
this declaration
namespace Main {
class B : A {
declares B as a class inheriting from A or some class in the current hierarchy of namespaces. The compiler will try Main::A and won't find it. It will then try the global namespace, ::A, and will also fail to find A there. It will certainly won't try namespaces that are outside the current namespace hierarchy, in particular, it certainly won't try Base::A. Having failed to find a class matching A, it will stop with an error.
The second error is in that you inherit the base class privately. This means that the information about this inheritance is invisible outside class B, so that you cannot call any of the base class members outside B.
Solution:
namespace Main {
class B : public Base::A {
Related
In a derived class If I redefine/overload a function name from a Base class,
then those overloaded functions are not accessable/visible to derived class.
Why is this??
If we don't overload the oveloaded function from the base class in derived class
then all the overloaded versions of that function are available to derived class
objects, why is this??
what is the reason behind this. If you explain this in compiler and linker level
that will be more helpful to me. is it not possible to support this kind of scinario??
Edited
For examble:
class B
{
public:
int f() {}
int f(string s) {}
};
class D : public B
{
public:
int f(int) {}
};
int main()
{
D d;
d.f(1);
//d.f(string); //hidden for D
}
Now object 'd' can't access f() and f(string).
TTBOMK this doesn't have a real technical reason, it's just that Stroustrup, when creating the language, considered this to be the better default. (In this it's similar to the rule that rvalues do not implicitly bind to non-const references.)
You can easily work around it be explicitly bringing base class versions into the derived class' scope:
class base {
public:
void f(int);
void g(int);
};
class derived : public base {
public:
using base::f;
void f(float);
void g(float); // hides base::g
};
or by calling the explicitly:
derived d;
d.base::g(42); // explicitly call base class version
The functions are available, you just need to call them explicitly:
struct A {
void f(){}
};
struct B : public A {
void f() {}
};
int main() {
B b;
b.f(); // call derived function
b.A::f(); // call base function
}
I have a base class A and two classes B, C derived from A. Declaration of method func is given in class A. How can I define method func separately for B and C ?
class A {
public:
void func();
};
class B : public A {
//some members
};
class C : public A {
//some members
};
//define B's func here without changing the definition of the three classes
//define C's func here without changing the definition of the three classes
You have to make the method you want to overwrite "virtual" or "pure virtual" and if a class has virtual methods, also the destructor must be virtual:
class A {
public:
virtual ~A{};
virtual void func() = 0;
};
class B : public A {
void func() {};
};
class C : public A {
void func() {};
};
No, you cannot implement a member function for a class without it being declared in the class.
class A {
public:
void func();
};
class B : public A {
//some members
};
class C : public A {
//some members
};
void B::func() {}
void C::func() {}
/tmp/164435074/main.cpp:17:9: error: out-of-line definition of 'func' does not match any declaration in 'B'
void B::func() {}
^~~~
/tmp/164435074/main.cpp:18:9: error: out-of-line definition of 'func' does not match any declaration in 'C'
void C::func() {}
^~~~
When a class is derived from a base class, will the member functions of the base class become member function of the derived class. That is, for example if I write:
class A
{
public : void f();
};
class B : public A
{
public : void f1();
};
Now if the question is to name the member functions in class B, then will f() also become a member function of class B ?
then will f() also become a member function of class B ?
No. f() is still a member function of class A, class B just inherits it. In your case it's a public member function and public inherit, means you can call f() on a B object.
B b;
b.f();
On the other hand, class B can define own member function f():
class A
{
public : void f();
};
class B : public A
{
public : void f(); // will hide A::f()
};
Yes, class B has two functions: f1() and f().
If f() was protected in A, too, but f() could only be used from within the member functions of A and B (and from friends).
And if f() was private, B would have only one function f1().
class A {
public : void f();
};
class B : public A
{
public : void f1();
};
Now code is valid.
It is visible. Even when you change f1 name to f it is still visible in B class. If you wanna use it use scope operator ::.
Like this:
A::f()
More about basic inheritence
http://www.learncpp.com/cpp-tutorial/112-basic-inheritance-in-c/
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
In a derived class If I redefine/overload a function name from a Base class,
then those overloaded functions are not accessable/visible to derived class.
Why is this??
If we don't overload the oveloaded function from the base class in derived class
then all the overloaded versions of that function are available to derived class
objects, why is this??
what is the reason behind this. If you explain this in compiler and linker level
that will be more helpful to me. is it not possible to support this kind of scinario??
Edited
For examble:
class B
{
public:
int f() {}
int f(string s) {}
};
class D : public B
{
public:
int f(int) {}
};
int main()
{
D d;
d.f(1);
//d.f(string); //hidden for D
}
Now object 'd' can't access f() and f(string).
TTBOMK this doesn't have a real technical reason, it's just that Stroustrup, when creating the language, considered this to be the better default. (In this it's similar to the rule that rvalues do not implicitly bind to non-const references.)
You can easily work around it be explicitly bringing base class versions into the derived class' scope:
class base {
public:
void f(int);
void g(int);
};
class derived : public base {
public:
using base::f;
void f(float);
void g(float); // hides base::g
};
or by calling the explicitly:
derived d;
d.base::g(42); // explicitly call base class version
The functions are available, you just need to call them explicitly:
struct A {
void f(){}
};
struct B : public A {
void f() {}
};
int main() {
B b;
b.f(); // call derived function
b.A::f(); // call base function
}