C++ Primer Plus(第6版)的技术点(2)

来源:互联网 发布:linux 查看tmp空间 编辑:程序博客网 时间:2024/05/21 16:56

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);}


11, 多继承和虚基类

这个概念在平时应用当中用的很少, 了解一下概念就行, 当有一个非常复杂的关系, 最终的派生类中, 可能会有两个相同的基类对象, 这时要使用虚基类. 在继承时加上virtual关键字.


12, 类模板

注意, 很多编译器不支持模板类分离编译, 所以, 模板类的声明和定义最好放在同一个文件里.

0 0
原创粉丝点击