首页 > 代码库 > 访问控制 protected, public, private 对比
访问控制 protected, public, private 对比
OOP 3大特性:数据抽象,继承,动态绑定
int main()
{
Base b, a;
Devi d;
3中访问标号
protected, public, private 对比
用类进行数据抽象;用继承类继承基类的成员,实现继承;通过将基类相应函数声明为virtual,是编译器在运行时决定调用基类函数or派生类函数 完成动态绑定,即表现多态性。
多态性:利用继承和动态绑定,通过基类指针和引用来表现。
动态绑定两个条件:1. 虚函数,2. 指针或引用
class Item_book
{
private:
std::string isdn;
protected:
double price;
public:
std::string book() const { return isdn; }
};
class Bulk_item::public Item_book
{
...
};
void Bulk_item::memfcn(const Bulk_item &d, const Item_base &b)
{
cout<<isdn;// error: no access to isdn which is private member in Item_base (1)
double ret = price; //ok: use this->price (2)
ret = d.price;// ok: use price from a Bulk_item object (3)
ret = b.price; // error: no access to price from an Item_base (4)
}
{
private:
std::string isdn;
protected:
double price;
public:
std::string book() const { return isdn; }
};
class Bulk_item::public Item_book
{
...
};
void Bulk_item::memfcn(const Bulk_item &d, const Item_base &b)
{
cout<<isdn;// error: no access to isdn which is private member in Item_base (1)
double ret = price; //ok: use this->price (2)
ret = d.price;// ok: use price from a Bulk_item object (3)
ret = b.price; // error: no access to price from an Item_base (4)
}
#include <iostream>
using namespace std;
class Base
{
private:
int age;
protected:
int num;
public:
using namespace std;
class Base
{
private:
int age;
protected:
int num;
public:
Base()
{
num = 5;
}
void set_num( const Base& a)
{
cout<<a.num<<endl;
}
virtual void show()
{
num = 1;
cout<<num<<endl;
}
};
class Devi : public Base
{
public:
void show()
{
num = 2;
cout<<num<<endl;
}
void test(const Base &a, const Devi &b)
{
cout<<b.num<<endl; //(5)
}
};
{
cout<<a.num<<endl;
}
virtual void show()
{
num = 1;
cout<<num<<endl;
}
};
class Devi : public Base
{
public:
void show()
{
num = 2;
cout<<num<<endl;
}
void test(const Base &a, const Devi &b)
{
cout<<b.num<<endl; //(5)
}
};
int main()
{
Base b, a;
Devi d;
b.set_num(a); (7)
b.show();
d.show(); //ok protected num可被子类使用
d.test(b, d);
//cout<<d.num; //error protected num 不可被子类 对象使用 (6)
return 0;
}
b.show();
d.show(); //ok protected num可被子类使用
d.test(b, d);
//cout<<d.num; //error protected num 不可被子类 对象使用 (6)
return 0;
}
区分(5)(6)的区别,一个在 类的成员函数定义中(可以通过 类对象调用其保护成员,如公有成员一样),一个在 类定义外部
总结:
访问控制与继承:
public:
private: 只能被基类的成员和友元函数访问。不能被类的对象访问。同时不能被派生类(的成员函数)访问。如下(1)。
protected:可以被派生类(的成员(2))访问。不可以被派生类对象访问(6)。例外:(例外:在派生类内部 可以通过派生类对象访问其基类的protected)如下(3),同时对比下图(5)和(6);
但不能被基类的对象访问(对于基类,相当于基类的private)如下(4);基类在基类内部可以通过基类对象访问其protected成员(7)
即 派生类可以访问基类 protected 和 public 中的成员。
公有、私有、保护继承
对类所继承的成员的访问由 基类的成员访问级别和派生类派生列表中使用的访问标号共同控制。
派生类可以进一步限制,但不能放松对继承的成员访问。
派生类中的访问级别(3种继承方式):
public:基类成员保持自己的访问级别:基类的public->派生类的public,基类的protected -> 派生类的protected。
protected:基类的public和protected成员在派生类中为proteced成员
private:基类的所有成员在派生类中为private成员。
class Base
{
public:
void basemen();
protected:
int i;
private:
std::string isdn;
....
};
class Public_derived: public Base
{
int use_base() { return i; } //ok: as proteced member in Public_derived
//...
};
class Private_derived: private Base //注意,对比下面
{
int use_base() {return i;} // ok: i is protected member in Base, private member in Pivate_derived
int print_isdn() {cout<<isdn; } //error: isdn is private member in Base
};
{
public:
void basemen();
protected:
int i;
private:
std::string isdn;
....
};
class Public_derived: public Base
{
int use_base() { return i; } //ok: as proteced member in Public_derived
//...
};
class Private_derived: private Base //注意,对比下面
{
int use_base() {return i;} // ok: i is protected member in Base, private member in Pivate_derived
int print_isdn() {cout<<isdn; } //error: isdn is private member in Base
};
派生访问标号 还控制来自非直接派生类的访问:
class Derived_from_Private: public Private_derived
{
//error: Base::i is private in Private_derived
int use_base() {return i;}
};
class Derived_from_Private: public Public_derived
{
//ok: Base::i remain proteced in Public_derived
int use_base() {return i;}
}
{
//error: Base::i is private in Private_derived
int use_base() {return i;}
};
class Derived_from_Private: public Public_derived
{
//ok: Base::i remain proteced in Public_derived
int use_base() {return i;}
}
struct VS class
struct 定义的类 默认范围级别为public类型,定义的派生类 默认具有public继承
class 定义的类 默认范围级别为private类型,定义的派生类 默认具有private继承
转换与继承
可以将派生类转换为基类---通过初始化或复制。 一般调用基类的复制构造函数或赋值函数。
例:
Item_base item; //object of base type
Bulk_item bulk; //object of derived type
//ok:use Item_base::Item_base(const Item_base&) constructor
Item_base item(bulk); // bulk is "slice down" to its Item_base portion
//ok:use Item_base::operator = (const Item_base&)
item = bulk; // bulk is "slice down" to its Item_base portion
Bulk_item bulk; //object of derived type
//ok:use Item_base::Item_base(const Item_base&) constructor
Item_base item(bulk); // bulk is "slice down" to its Item_base portion
//ok:use Item_base::operator = (const Item_base&)
item = bulk; // bulk is "slice down" to its Item_base portion
基类 不能自动 转换为派生类,否则派生类会访问 不存在的成员 (基类不存在的成员),
除非在 知道 基类向派生类转换为 安全时,可以使用 static_cast强制编译器进行转换。或是
用 dynamic_cast 申请在运行时进行检测。
参照 《C++ primer》 第15章
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。