您的位置:首页 > 编程语言 > C语言/C++

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

2015-01-17 12:59 253 查看
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, 类模板

注意, 很多编译器不支持模板类分离编译, 所以, 模板类的声明和定义最好放在同一个文件里.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: