类(初学)(2)

警告:本文是用来学习有关类的知识点,由于初学,所以必会犯很多错误,请大家酌情观看

参考博客:C++ public、protected 、 private和friend(最通俗易懂)
参考博客:c++ public protected private个人理解总结

1、继承(补充)
各个参数的范围:public > protected > private
当前类继承父类时:无论何种继承,父类的private部分都不可直接访问

下面是继承后的访问控制:(前面是什么可以访问类,后面是类可以访问什么
public:当前类 + 子类 + 对象 可访问父类的public,protected
protected:当前类 + 子类 可访问父类的public,protected
private:当前类 可访问父类的public,protected
(上面说的 对象 指 类的对象,不理解直接看例子)

举例:

#include <iostream>
using namespace std;

class A{
public:
    A(int x,int y):x(x),y(y){}
    void show(){print();}  //基类成员可以直接调用protected成员
protected:
    void print()
    {cout<<"x point:"<<x<<endl<<"y point:"<<y<<endl;}
private:
    int x;
    int y;
};
class B:public A{
public:
    B(int x,int y,int z):A(x,y),z(z){}
    void output() 
    {print();   //子类成员可以直接调用基类protected成员
    cout<<"z point:"<<z<<endl;}
private:
    int z;
    void another(){print();} //当然,非public成员也能访问基类protected成员
};
int main()
{
    A a(2,3);
    B b(4,5,6);
    //a.print();//不可以,基类对象不能调用自身protected成员
    a.show();//可以,基类对象调用public成员,间接调用protected成员
    //b.print();//不可以,子类对象不能调用基类protected成员
    b.output(); //可以,子类对象调用自身public成员,该成员函数内部调用了基类保护成员print()
    return 0;
}

一般来说继承都是用public

2、覆盖(override,也称 重写)

作用是修改从 基类 继承下来的函数,方法是在 子类 重新 声明并定义

#include <iostream>
using namespace std;

class A{
public:
    void eat();
    void ate();
};
class B:public A{
public:
    void eat();
    void ate();
};

void A::eat()
{
	cout<<"基类eat"<<endl;
}
void A::ate()
{
	cout<<"基类ate"<<endl;
}
void B::eat()
{
	A::eat(); //调用基类 eat()函数 
	cout<<"子类eat"<<endl;
}
void B::ate()
{
	cout<<"子类ate"<<endl;
}
int main()
{
    B b;
    b.eat();
    cout<<endl;
    b.ate();
    return 0;
}
output:
基类eat
子类eat

子类ate

说明在重载时可以调用 基类原函数(也可以不调用)

3、重载

有关重载, 我曾在这篇博客讲过:初学者该注意的地方(C++程序设计教程),在第9节,还希望大家把第10节(默认函数)也一起看了,因为函数重载和默认参数一起用时,可能会出现二义性(有矛盾的意思),大家可以了解一下

4、友元
参考博客:友元函数 友元类 友元成员函数

一般来说,类内的私有数据是对外不可见的,但在有些情况下,我们需要在类外对该类的私有数据进行访问,这就需要用到一种新技术——友元(friend),即在声明前添加关键字friend

友元关系是单向的,即如果A是B的友元,但B不一定是A的友元;
友元关系无传递性,即如果A是B的友元,B是C的友元,但A不一定是C的友元

① 友元函数

友元函数是指某些非类成员函数,但可以访问类内的 私有数据(protected 和 private)

#include <iostream>
using namespace std;

class A {
private:
    int data;
public:
    A() : data(1) {}
    friend void show( const A& t );  //添加 friend定义友元函数
};  

/* 友元函数在类外声明时不加 friend */
void show( const A& t ) {
    cout << "data = " << t.data << endl;  
}

int main(void) {  
    A a;
    show(a);  

    return 0;  
}
output:
data = 1

② 友元类

友元类是指若需要在类B中直接访问类A的私有数据,因此将B作为A的友元(在A中声明friend class B
友元类中的成员函数、私有数据都可以在另一个类中被使用(即类B中可以直接使用类A的私有数据等)

class Tv {
private: 
    int state;
public: 
    friend class Remote;  //声明 Remote为 Tv的友元类
    enum{ Off, On };

    Tv( int s = Off ) : state(s) {}
    void onoff() { state = (state == On) ? Off : On; }
};

class Remote {
public: 
    void onoff( Tv & t ) { t.onoff(); }
};

③ 友元成员函数

友元成员函数是指类中的一个成员函数被定义为友元函数
与友元类不同的是,只有友元成员函数可以在另一个中被使用,其余函数都不可以

#include <iostream>
using namespace std;

class B;  //前向声明

class A{
private: 
    int a;
public: 
    A() { a = 1; }
    void print( B & b );
};

/* 示例位置1 */

class B{
private: 
    int b;
public: 
    B() { b = 6; }
    void print() { cout << b << endl; }
    friend void A::print( B & b );  //友元成员函数
};

/* 被定义为友元成员函数的函数必须在类外(另一个使用该函数的类后面)定义 */
void A::print( B & b ) {
    cout << "b = " << b.b << endl;
}

int main() {
    A a;
    B b;
    a.print( b );

    return 0;
}
output:
b = 6

需要注意的是:
(1)类的前向声明。由于在A中的print函数需要使用B,如果不进行B的前向声明,编译器就不知道B是一个类,会报错。
(2)类的排列顺序。在类B中会用到A的方法print(),因此需要先定义A,再定义B。
(3)友元成员函数的定义位置。友元成员函数不能使用内联代码,类中只能有函数声明。函数定义需要放到类之后,在类外进行定义,而且必须放到另一个类定义的后面。(对上面代码来说,若将A::print()的定义放在类B定义之前——示例位置1处,也会报错,提示类B未完成)

5、静态属性 和 静态方法

静态属性 也称 静态成员
静态方法 也称 静态函数

具体的内容在此贴个博客:C++ 类(静态成员和静态函数),因为我现在还不是很了解,理解后再回来补充

下一章:类(初学)(3)

发布了92 篇原创文章 · 获赞 35 · 访问量 6374

猜你喜欢

转载自blog.csdn.net/CourserLi/article/details/103610140