学习C++的一些笔记(二)

来源:互联网 发布:张靓颖是冯轲的m知乎 编辑:程序博客网 时间:2024/06/14 08:05
31.构造函数构造函数的过程,分为2个阶段执行的,第一个阶段就是初始化列表的,初始化阶段。第二个是普通继承阶段,如
Student(int id, string &name,  int age)
{
id_ = id;
name_ = name;
age_  = age;
}完成了继承。同时也可以写成Student(int id, string &name,  int age) : id_(id), name_(name), age_(age){}(此为构造函数)冒号前面为初始化阶段,冒号后面为继承阶段。(通过括号赋值。
32.不管初始化列表里变量顺序是什么样的,对每一个变量的初始化都是按变量在内容中的位置决定的,(具体见 mac 0710 x.cc)如:
class X
{
public:
X(int ival): ival2_(ival),ival1_(ival2_){}
private:
int ival1_;
int ival2_;
}
33.虽然表面上看是先把ival值赋给ival2_,再由ival2_赋给ival1_,但是由于private中先出现ival1_,所以ival1_初始化是在ival2_之前,最后结果是ival2_的值没有赋给ival1_。
34.对于类里面的每一个成员函数,都隐藏了一个this指针,这个this指针指向的都是对象本身。通过一个*取地址,得到对象本身,再返回一个引用,引用就是对象本身。(一种链式编程的方式)特别是,当我们需要将一个对象作为整体引用,而不是引用对象的一个成员时,需要用到this指针(this指针变量记录了当前对象的内存地址,函数体内,对所有类成员的访问,都会转化为this->数据成员的方式,如cout << “ival_” << ival_ <<endl; ==> cout <<“ival_” << this->ival_ << endl; ),this指针初始化是在程序调用的时候,即一个类的对象调用成员函数的时候。进过编译器处理,地址就赋给this指针(一般出现类似于如,Screen &Screen::set(char c)这样的成员函数时,该函数的返回值都为*this)
35.销毁一个对象的函数,就是析构函数,写法是~Student(){},即~加上类名。析构函数没有返回类型,也不要能指定参数,析构函数也就只有一个,不能被重载
36.在函数中加上一个{},代表一个语句块,出了这个语句块,里面的变量生命周期就结束了。如:
string name = ”lisi"
{
Student s;
……
},当语句块结束后,会自动调用析构函数
37.在main函数中,只要不是new出来的对象,都是放在栈中
38.类在内存中的内存布局是由类中的成员数据所决定的,当为一个空类时,所占字节为1(区别对象跟对象,因为对象的地址是不一样的,分配了地址必须有内容,所以为1),因为经过编译器编译后,会给类一个隐含的地址,这样就可以区分不同的对象。
39.当把一个已经存在的对象赋值给另一个新的对象时。当实参和形参都是对象,进行形参和实参的结合时。当函数的返回值是对象,函数调用完成返回时。拷贝构造函数会自动调用。复制构造函数只在初始化时候调用。如point pt1 = pt2; 此时会调用复制构造函数,将pt2复制给pt1。而point pt3; pt3 = pt4;此时则不会调用复制构造函数,因为前一语句已经初始化完成,pt3 = pt4只是一个简单的复制操作,调用一个复制操作符
40.为什么复制构造函数const 类名里面要用引用的方式(类名::类名(const 类名 &)),如果不是引用,就会发生一个形参到实参的转换,就会发生无限的递归
41.每一次用new时,都要判断指针是否合法
42.创建一个对象时,分为三步,1.是通过调用operator new操作符,开辟一个空间。2.开辟完后在调用构造函数(初始化的过程)。如果构造函数调用失败,则对象创建失败,同时也造成内存泄露。因为之前operator new已经生成空间。3.返回指向新分配并构造的对象的指针。
43.隐式转换,如果对一个类进行数字赋值,也可以编译通过,是因为,Point pt1 = 1==>>Point pt1 = point(1);如何屏蔽隐式转换,可以在函数前加上explicit,即可
44.const数据成员的初始化,只能在初始化表中进行初始化,如
class Point
{
public:
Point(int ix, int iy): ix_(ix), iy_(iy)(此为初始化表)  而不可以  Point(int ix, int iy)
{                                                                                              {
}                                                                                               ix_ = ix;
private:                                                                                    iy_ = iy;
const int ix_;                                                                            }
const int iy_;
}同理,引用,类对象成员也只能在初始化表中初始化(复制构造函数也是)
45.构造函数的作用是使类的成员变量有合适的初值。调用时机是在创建该类对象的时候。复制构造函数,是指类的对象在创建时候的时候,能使用已有的对象来初始化新创建的类
46.static(static对象存储在全局区,对类的每一个对象都是共享的)成员初始化必须在类申明之外进行,且不包含static关键字。如:
class Computer
{
public:
……
private:
static float fTotalPrice_;
static Point pt1_;
};
float Computer::fTotalPrice_ = 0.0;
Point Computer::pt1(3,4);
int main(void)
{
……
}
47.如果函数不修改数据成员,则在后面直接加上const,保护数据成员不被修改
48.静态成员函数没有this指针,静态成员函数是整个类共享的,只能操作静态成员函数和数据(即使为空指针也能调用)
49.引用数据成员在class中相当于是指针来布局的,指针所占字节数只与机器的寻址能力有关,在64位机器上为8个字节
50.赋值运算符(当类中出现指针),将类对象赋值时需要对运算符功能进行重载,(格式为,返回类型 类名::operator 运算符(参数列表){函数体},如:
Computer &(此为返回类型,防止返回时再次调用复制构造函数,所以为引用,又因为如果是在类中定义可以省略类名)operator=(Computer &rhs){})
51.operator new(void *operator new(size_t)或者void *operator new[](size_t))和operator delete(void operator delete(void *p)或者void operator delete[](void *p))函数,在程序之中要加上static,因为防止有this指针,如果不加,则没有重载功能
52.只生成一个栈对象,意味着不能通过new表达式创建对象,只需将operator new列为private。只生成堆对象,只需要把构造函数或者析构函数放入private
53.const成员函数,只能读取类成员函数,而不能修改。只能调用const成员函数,不能调用非const成员函数(因为未加const时,void print(); =>void print(Point *const this) ,非const对象能调用const函数)
54.单例模式是指在程序运行的过程中,某一个类只有一个(不管运行多少次,在内存中只保存一份副本)如,日志系统。(使用static定义函数,变量为指针,然后将构造函数设为privated)
55.一旦带指针的类需要手动去写析构函数(即手动释放),那么我们也需要一个手动的赋值操作符和一个复制构造函数(即三法则,如果类需要析构函数,则它也需要赋值操作符和复制构造函数)
56.对象数组,与标准化数组类似。格式为Point apt1[2] ={Point(3, 4), Point(5 , 6)};
Point apt2[] = {Point(7, 8), (9, 10)}; 如果要写成Point apt3[5] = {Point(11, 12), (13, 14)}需要在申明中显式的写出默认构造函数(Point():ix_(0), iy_(0)),或者可以在自定义构造函数中进行初始化如:Point(int ix= 0,int iy = 0):ix_ (ix), iy_(iy)。这样才正确,并且,第三位开始为(0 ,0)。
57.打破封装访问类的私有成员,要用友元(在类的定义中用friend申明了一个外部函数,或者其他类的成员函数后,这个函数就叫友元)友元可以非为3种情况,1.是把非成员函数定义为友元,或者把一个类定义为友元,也可以定义一个成员函数定义为友元
58.友元函数的申明既可以在public里面也可以在private里面
59.A类成员函数成为B类的友元时必须,先定义A类,而不是声明
60.类跟函数一样,也有前向声明
原创粉丝点击