15、C++ Primer 4th 笔记,类和数据抽象,友元
1、成员可以是数据,函数或类型别名(typedef定义的)。
2、const必须同时出现在声明和定义中。
3、重载的成员函数和普通函数应用相同的规则:两个重载成员的形参数量和类型不能完全相同。也可以根据const来定义。
T& display(std::ostream &os)
{
...
}
const T& display(std::ostream &os) const
{
...
}
4、inline在声明和定义处指定都是合法的。
5、可以声明一个类而不定义它,这个声明有时称为前向声明(forward declaration),声明的类是一个不完全类型(incompete type)。
不完全类型只能以有限方式使用。不能定义该类型的对象。不完全类型只能用于定义指向该类型的指针及引用;或者用于声明(而不是定义)使用该类型作为形参类型或返回类型的函数。
一般用于编写相互依赖的类。
6、为只有当类定义体完成后才能定义类,因此类不能具有自身类型的数据成员。然而,只要类名一出现就可以认为该类已声明。因此,类的数据成员可以是指向自身类型的指针或引用。
7、成员函数不能定义this形参,由编译器隐含指定。成员函数的函数体可以显式使用this指针,但不是必须这么做。
有一种情况必须使用:当我们需要一个对象作为整体引用而不是引用对象的一个成员时,如一个函数返回调用该函数的对象的引用。
class1& class1::set(char c)
{
...
return *this;
}
8、在非const成员函数中,this的类型是一个指向类类型的const指针。在const成员函数中,this的类型是一个指向const类类型对象的const指针。不能从const成员函数返回指向类对象的普通引用,只能返回*this作为一个const引用。
const对象只能使用const成员,非const对象可以使用任一成员。
9、我们希望类的数据成员(包括const成员函数)可以修改,可以把它们声明为mutable。
10、一般的数据或函数成员必须通过对象来访问。定义类型的成员,则使用作用域操作符来访问。
11、形参表和函数体处于类作用域中;函数返回类型不一定在类作用域中,如果函数在类定义体之外定义,则用于返回类型的名字在类作用域之外。如果返回类型使用由类定义的类型,则必须使用完全限定名。
12、名字必须在使用之前进行定义。而且一旦一个名字被用作类型名,该名字就不能被重复定义,与定义局部变量内层变量名覆盖外层变量名不同。
13、友元以friend声明,它只能出现在类定义的内部。一般把它放在类定义的开始或结尾是个好主意。
必须先定义包含成员函数的类,才能将成员函数设为友元。不必预先声明类和非成员函数来将它们设为友元。
14、类必须将重载函数集中每一个希望设为友元的函数都声明为友元。
(1) 友元的关系是单向的而不是双向的。
(2) 友元的关系不能传递。(A是B的朋友,B是C的朋友,但不一定A是C的朋友)。
(3) 但是友元可以继承(这是我在VS编译器中测试的结果,在C++ Primier中说其不可以继承)。
示例
#include <iostream>
using namespace std;
class Data;
class Time
{
public:
Time(int,int,int);
void display(Data&);
private:
int hour;
int minute;
int sec;
};
class Data
{
public:
Data(int,int,int);
friend void Time::display(Data&);
private:
int month;
int day;
int year;
};
class Date1:public Data
{
public:
Date1(int m1, int m2, int m3):Data(m1,m2,m3)
{
cout << "In Date1" << endl;
}
};
Time::Time(int h,int m,int s)
{
hour=h;
minute=m;
sec=s;
}
void Time::display(Data& d)
{
cout<<d.month<<"/"<<d.year<<endl;
cout<<hour<<":"<<minute<<":"<<sec<<endl;
}
Data::Data(int m,int d,int y)
{
month=m;
day=d;
year=y;
}
int main()
{
Time t1(10,13,56);
Data d1(12,25,56);
t1.display(d1);
Date1 dd1(1,2,3);
t1.display(dd1);
return 1;
}
参考
[1] 友元
http://blog.163.com/zhoumhan_0351/blog/static/39954227201002621251123/
[2] 继承
http://blog.163.com/zhoumhan_0351/blog/static/3995422720100284731826/