C++复习封装(多验证)

实例化:

从栈实例化对象:系统自动回收

TV tv1;

从堆实例化对象:delete释放内存

TV *p = new TV();
TV *q = new TV[20];
delete p;
delete []q;

对象成员访问

栈:对象 加 .

int main()
{
    TV tv;
    tv.type = 0;
    tv.changeVol();
    return 0;
}

堆:指针 加 ->

int main()
{
    TV *p = new TV();
    p->type =0;
    p->changeVol();
    delete p;
    p = NULL;
    return 0;
}

String

初始化string对象:
string s1;
string s2(“ANC”);
string s3(s2);
string s4(n,‘c’); 将s4初始化为字符’c’的n个副本。
常用基础操作:
s.empty(); 空返回true,否则false
s.size(); 返回s中字符个数
s[n]; 返回s中位置为n的字符,位置从0开始
s1+s2 返回连接后的新串
s1 = s2 将s1内容替换为s2的副本
s1 == s2 相等返回true,否则false
字符串常量之间+是非法的,+两边必须至少有一个为string对象
而非常量"xxx"

类内定义和内联函数

内联函数:关键字inline:编译时将函数体代码和实参代替函数调用语句。必须是结构很逻辑比较简单的代码,才能保证效率快。
普通函数:main()调用普通函数->找到函数入口->运行函数的代码->结束后返回到主调函数。

类内定义就是成员函数的定义在类中。类内定义的成员函数(简单的)会自动看作inline函数。

类外定义是指成员函数的函数体写在类的外面:
1.同文件类外定义(类定义与成员函数定义在同一个文件中)
需要在每个函数前面用类名 加上 :: 来标识
2.分文件类外定义:
定义一个与类名(Car)相同名字的头文件(Car.h)
再在Car.cpp中加上#include “Car.h”
实现成员函数的定义同样是要在每个函数前面用类名 加上 :: 来标识。

内存分区

栈区:定义变量。内存由系统分配。

int x = 0;
int *p = NULL;

堆区:new分配的内存,需要自己管理。

int *p = new int[20];

全局区:存储全局变量及静态变量。
常量区:存储常量

string str = "hello";

代码区:存储逻辑代码的二进制

构造函数

class student
{
public:
    Student(){}
    Student(string name = "Jim")
private:
    string m_strName;
};
int main()
{
    Student stu1();
    Student *p = NULL;
    p = new Student();
    return 0;
}

初始化列表

class student
{
public:
    Student():m_strName("Jim"),m_iAge(10){}
private:
    string m_strName;
    int m_iAge;
};

初始化列表先于构造函数执行。
初始化列表只能用于构造函数。
初始化列表可以同时初始化多个数据成员,速度高,效率快。

初始化列表的必要性:
类中的不变的成员变量(常量,比如PI),必须通过初始化列表。

拷贝构造函数
定义格式:类名(const 类名& 变量名)

构造函数分为无参构造函数(默认构造函数)和有参构造函数(分为参数带默认值和参数不带默认值)。

还有相关的小点:

1.深、浅拷贝:

有指针类型的数据成员时,在main中 obj1 = obj2来创建对象对其初始化时需要在类中定义深拷贝构造函数(即需要将指针指向的内存中的变量一一赋值)

2.对象数组

…就是一下定义好多对象呗 new的时候 类名后面不是()而是[n]… n是数组中元素个数

3.对象指针:

指向对象的指针,指针指向的内存就是对象里第一个数据成员的地址,可以 p->来访问对象数据成员,也可以用(*p). 来访问,前者是指针,后者是对象。

4.对象成员指针:

某个类对象的指针作为另一个类的成员。可以初始化列表进行初始化(直接()里NULL就行),也可以进行普通的初始化,还可以m_a = new C(1,3);在用其构造函数堆中创建对象,但要注意这种需要在我们的当前类的析构函数里加上delete语句释放。

5.this指针:

指向对象自身数据的指针。 this指针就是&当前对象。在类中的方法中都隐藏了this指针参数,所以调用的时候也隐藏了this指针,实际上是存在的,由此不会产生对象错乱的情况。

6.const:

类的数据成员可以用const来修饰,基本数据类型的数据成员用const修饰时,需要用初始化列表来初始化给它一个不变的值。

class Coordinate
{
public:
	Coordinate(int x,int y);
private:
	const int m_iX;
	const int m_iY;	
};

Coordinate::Coordinate(int x, int y):m_iX(x),m_iY(y)
{
}

7.常对象成员:

一旦初始化就不能再修改的对象成员。

class Line
{
public:
	Line(int x1, int y1, int x2, int y2);
private:
	const Coordinate m_coorA;
	const Coordinate m_coorB;
};

Line::Line(int x1,int y1, int x2, int y2):m_coorA(x1,y1),m_coorB(x2,y2)
{
}

int main{

	Line *p = new Line(2.1.6,4);
	delete p;
	p = NULL;
	return 0;
}

8.常成员函数:

常成员函数中不能修改成员函数的值。

class Coordinate
{
public:
    Coordinate(int x, int y);
    void changeX() const;  //常成员函数和下面这个函数是互为重载
    void changeX();
private:
    int m_iX;
    int m_iY;
};

void Coordinate::changeX()
{
    m_iX = 20;
}

int main()
{
    Coordinate coordinate(3,5);
    coordinate.changeX();  //调用的是不带const的成员函数
    return 0;
}

函数定义实际上隐藏了this指针,等价于:

void Coordinate::changeX(Coordinate *this)
{
    this->m_iX = 20;
}

为什么函数类外定义的时候不在后面也加上const呢?
因为定义时加上const后,this指针就变成了常指针:const Coordinate *this
此时它指向的数据m_iX是不能被修改的,即this->m_iX = 20;会出错。

怎样能调用const修饰的成员函数呢?

int main()
{
    const Coordinate coordinate(3,5);  //定义一个常对象
    coordinate.changeX();  //通过常对象调用const修饰的成员函数
    return 0;
}

9.常指针,常引用:

在对象指针或对象引用前加上const。

对象引用可以直接赋值初始化,而对象指针需要给赋值对象加一个引用:

Coordinate coor(3,5);
Coordinate &coor2 = coor1;
Coordinate *pCoor = &coor1;

常引用或常指针只有一个读权限,而getX();函数中隐藏的this要求的是读写权限的参数,所以如果coor2.getX();或Pcoor->getY();会报编译错误。想要调用成员函数只能调用printInfo():

Coordinate coor(3,5);
const Coordinate &coor2 = coor1;
const Coordinate *pCoor = &coor1;

如果是下面这样:

Coordiante * const pCoor = &coor1;

那么pCoor就只能指向coor1这一个对象,不能指向其他对象。但指针是具有读写权限的,所以可以调用getY();

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章