#include <iostream>
#include <string>
struct Base {
int _m;
};
struct Derived : public Base {
// hide visibility of Base::_m
std::string _m;
void foo();
};
void Derived::foo(){
_m = "123";
//_m = -1; // Error
}
int main(){
Derived d;
d.foo();
std::cout << d._m << "\n";
return 0;
}
#include <iostream>
#include <string>
struct Base {
void Foo(int){ }
};
struct Derived : public Base {
void Foo(std::string){ }
void Bar(std::string){
//Foo(1); // Error
}
};
int main(){
Derived obj;
obj.Foo("55");
obj.Foo(1); // Error
return 0;
}
#include <iostream>
#include <string>
struct Base {
void Foo(int){
std::cout << "Called Base::Foo(int)\n";
}
};
struct Derived : public Base {
void Foo(std::string){
std::cout << "Called Derived::Foo(std::string)\n";
}
void Foo(int x){
Base::Foo(x);
}
};
int main(){
Derived obj;
obj.Foo(1); // Called Base::Foo(int)
return 0;
}
Method 2:
#include <iostream>
#include <string>
struct Base {
void Foo(int){
std::cout << "Called Base::Foo(int)\n";
}
};
struct Derived : public Base {
void Foo(std::string){
std::cout << "Called Derived::Foo(std::string)\n";
}
using Base::Foo;
};
int main(){
Derived obj;
obj.Foo(1);
return 0;
}
In effect, the using declaration enters each named member of the base class into the scope of the derived class. The base class member is now entered into the set of overloaded instances associated with the name of the member function within the derived class. (The using declaration for a member function cannot specify the parameter list, only the member function name. This means that if the function is overloaded within the base class, all the overloaded instances are added to the scope of the derived class type. We cannot add only one instance of the set of overloaded base class members.)
Base may directly access the _m data member, while the rest of the program must use the public access function. What this means, however, is that the derived class has access to the protected _m data member of its base class subobject. The derived class does not have access to the protected members of an independent base class object. For example:
#include <iostream>
#include <string>
struct Base {
Base () : _m(-2) { }
int get() { return _m; }
void set(int m) { _m = m; }
protected:
int _m;
};
struct Derived : public Base {
void Foo( Base *ptr ){
//ptr->_m; // Error
std::cout << ptr->get() << "\n"; // 300
std::cout << _m << "\n"; // -2
}
void Bar( Derived *ptr ){
std::cout << ptr->_m << "\n"; // -2
std::cout << ptr->get() << "\n"; // -2
std::cout << _m << "\n"; // -2
}
};
int main(){
Base* ptr_b = new Derived;
ptr_b->set(300);
Derived d1, d2;
d1.Foo(ptr_b);
d1.Bar(&d2);
return 0;
}
This form of member access constraint does not apply within a class for other objects of its own class (Derived::Bar(Derived&)). The derived class may access directly the protected base class members of other objects of its own class, as well as the protected and private members of other objects of its own class.
Base* ptr:
Base* ptr.Base* ptr.XX(), for example, an attempt to invoke it through Base* ptr results in a compile-time error.Base* ptr, a compile-time error results.
```c++
#include struct Base { Base() : _m(-1) {} void Foo(){ std::cout « “Calls Base::Foo()\n”; } virtual void Bar(){ std::cout « “Calls Base::Bar()\n”; } int _m; };
struct Derived : public Base { Derived() : _m(-2) {} void Foo(){ std::cout « “Calls Derived::Foo()\n”; } void Bar() override { std::cout « “Calls Derived::Bar()\n”; } virtual void XX(){ std::cout « “Calls Derived::XX()\n”; } void YY(){} int _m; };
int main(){
Base* ptr1 = new Derived;
// Case 1:
ptr1->Foo(); // Calls Base::Foo()
ptr1->Bar(); // Calls Derived::Bar()
// Case 2:
std::cout << ptr1->_m << "\n"; // -1
// Case 3:
//ptr1->XX(); // Error
// Case 4:
//ptr1->YY(); // Error
Derived* ptr2 = new Derived;;
ptr2->Foo(); // Calls Derived::Foo()
ptr2->Bar(); // Calls Derived::Bar()
ptr2->XX(); // Calls Derived::XX()
return 0; } ```
#include <iostream>
struct Base {
static int s_m;
};
struct Derived : public Base {
};
int Base::s_m = -56;
int main(){
Derived d1, d2;
std::cout << d1.s_m << "\n";
std::cout << d2.s_m << "\n";
return 0;
}