1, 内联方法
定义位于类声明中的函数都将自动成为内联函数.
2, 类中的常量
类中的常量(const成员)不能在声明中给出定义, 每个对象所拥有的常对象是不一样的, 而const成员变量只能在初始化时完成, 也就是在构造函数中完成.
3, 运算符重载限制:
= 赋值运算符, ()括号运算符, []下标运算符, ->指针访问运算符 这些运算符只能通过成员函数进行重载.
4, 友元(CPP 391)
友元有3种: 友元函数, 友元类, 友元成员函数.
非成员函数不能直接访问类的私有数据, 至少常规非成员 函数不能访问. 然而, 有一类特殊的非成员函数可以访问类的私有成员, 它们被称为友元函数.
创建友元函数的第一步是将其原型放在类声明中, 并在原型声明前加上关键字friend.
#include <iostream>
class myclass
{
private:
int a_;
friend void Fun(const myclass & m);
friend myclass operator+(const myclass & lhs, const myclass & rhs);
public:
explicit myclass(int a) : a_(a) {}
};
void Fun(const myclass & m)
{
std::cout<<m.a_<<std::endl;
}
myclass operator+(const myclass & lhs, const myclass & rhs)
{
myclass m(lhs.a_ + rhs.a_);
return m;
}
int main(int argc, std::string argv[])
{
myclass m(1);
Fun(m);
std::cin.get();
exit(0);
}
在作运算符重载时, 可以通过友元的方式来进行重载
在定义运算符时, 必须选择其中的一种格式, 而不能同时选择这两种格式.因为这两种格式都与同一个表达式匹配, 同时定义这两种格式将被视为二义性错误, 导致编译错误.
5, 类作用域
类成员除了static 以外都是类作域范围, 当一个对象存在时, 该对象内置的类型对象都存在, 在一个对象析构时, 内置对象析构.
当所有的内置对象初始化完成, 该对象才完成本身的构造函数.
当所有的内置对象析构, 该对象才完成析构.
当类中声明一个枚举类型时, 该枚举是类的作用域, 即在类外是不可见的.即使是public也是一样, 除了该类的内部以外, 其他地方不可访问.
6, 转换函数
在类中声明:
operator int() const;
operator myclass() const;
注意这种语法, 转换函数虽然没有明确指定必须为const但应注意, 定义类似的函数就可以强转为相应的类型.
7, 什么不能被继承(CPP 527):
构造函数, 析构函数, 赋值运算符和类的友元函数, 是不能被继承的.友元函数并非类成员.
8, 基类, 派生类中的赋值运算符
如果对象属于派生类, 编译器将使用基类赋值运算符来处理派生对象中基类部分的赋值.如果显示地为基类提供了赋值运算符, 将使用该运算符, 下面是例子:
#include <iostream>
class mybase
{
int a;
public:
mybase(int a) : a(a) {}
virtual ~mybase() {}
mybase & operator=(const mybase & b)
{
this->a = b.a;
return *this;
}
};
class myclass : public mybase
{
public:
myclass(int a, int b) : mybase(a), b(b) {}
virtual ~myclass() {}
myclass & operator=(const myclass & c)
{
mybase::operator=(c);
this->b = c.b;
return *this;
}
private:
int b;
};
int main(int argc, std::string argv[])
{
myclass m(10, 2);
myclass t1 = m;
myclass t2(1, 5);
t2 = m;
std::cin.get();
exit(0);
}
9, 初始化顺序
当初始化列表包含多个项目时, 这些项目被初始化的顺序为它们被声明(不是在构造函数的形参中声明, 而是在类中声明)的顺序, 而不是它们在初始化列表中的顺序.
10, 私有继承
其类指针(或引用)将无法指向通过私有或保护继承的派生类对象.只有is-a关系才能这样作, 而private继承属于has-a关系.
当私有(或保护)继承后, 派生类对象, 也无法访问基类的公有成员, 但可以使用using关键字重新定义访问权限:
#include <iostream>
class myclass2
{
public:
int a;
myclass2(){ std::cout<<"myclass2"<<std::endl; }
void Fun() { std::cout<<"hello myclass2"<<std::endl; }
};
class myclass3 : private myclass2
{
public:
myclass3() {}
using myclass2::Fun;
};
int main(int argc, std::string argv[])
{
myclass3 m3;
m3.Fun();
std::cin.get();
exit(0);
}
这个概念在平时应用当中用的很少, 了解一下概念就行, 当有一个非常复杂的关系, 最终的派生类中, 可能会有两个相同的基类对象, 这时要使用虚基类. 在继承时加上virtual关键字.
12, 类模板
注意, 很多编译器不支持模板类分离编译, 所以, 模板类的声明和定义最好放在同一个文件里.