Student(const Student &s) {
cpp_score = s.cpp_score;
math_score = s.math_score;
Eng_score = s.Eng_score;
id = s.id;
// 复制姓名(字符串)
name = new char[strlen(s.name) + 1];
strcpy(name, s.name);
}
delete []p;//释放这个空间
栈区(Stack)和堆区(Heap):栈是一种线性数据结构,堆是一种非线性数据结构,堆用于动态分配内存,堆中的数据具有较长的生命周期,栈的内存管理由编译器和程序自动处理,通常是静态分配,堆区访问速度更慢。
int main()
{
Line *p=new Line(2,1,6,4);
delete p;
p=NULL; //delete p; 语句用于释放 p 指针指向的动态分配的内存并销毁 Line 类的对象。然而,这并不会将指针 p 本身设置为 nullptr 或空指针。指针 p 仍然保留着之前分配的内存地址,尽管该内存已经被释放。
将指针设置为 nullptr 的目的是为了避免出现悬挂指针(dangling pointer)的情况。悬挂指针是指指向已经释放的内存的指针,访问这样的指针可能导致未定义的行为,甚至程序崩溃。
return 0;
}
Line::Line(int x1,int y1, int x2,int y2): m_CoorA(x1,y1),m_CoorB(x2,y2) //改进之后构造方法
{
cout<<"Line()…"<<endl;
};
只要成员变量涉及指针,就要注意深拷贝与浅拷贝。
class Array
{
public:
Array(){
x1=5;
x2=new int[x1];
}
Array(const Array& arr)//记得写const与&符号
{
x1=arr. x1;
x2=new int[x1];
for(int i=0;i<x1;i++)
{x2[i]=arr.x2[i];}}
private:
int x1;int *x2;
};
p->m_iY=20; //(*p).m_iY=20;
//对象的指针
class Line
{
public:
Line();
~Line();
private:
Coordinate *sa;
Coordinate *sb;
};
Line::Line() // 其对象的大小为8,因为为两个int类型的指针。
{
sa= new Coordinate(1,3);
sb= new Coordinate(5,6);
}
Line:: ~Line()
{
delete sa;
delete sb;
}
//this 指针解决同名的问题,指向本对象的首地址。
class Array
{
public:
Array(T *this,int _len){
this->len = _len;
}
int getLen(T *this){
return this->len;
} //T *this 只不过是显式使用这个的方法,但根本不需要。
void setLen(T *this, int _len){
this->len = _len;
} //将 T 用作占位符类型,以代表 Array 类。然而,这不是 C++ 中的正确用法。this 指针通常是隐式的,并且你不需要在参数列表中显式指定它。
private:
int len;
};
this指针也是指针类型,所以在32位编译器下也占用4个基本的内存单元,即sizeof(this)的结果为4。
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) { //常对象成员只能以这种方式来赋值,不能在函数体内写。
cout<<"Line "<<endl;
};
void Coordinate::changeX() const { //常成员函数中不能修改数据成员的值,确保不能被修改,
m_iX=10; //只能够被访问。
}; // wrong
void changeX(const Coordinate *this) { //指向的是常量对象
this->m_iX=10; // wrong
};//以上两种写法等效,都不能修改
int main() {
const Coordinate coord (3,5);
coord.changeX(); //调用的是常成员函数
return 0;
};
Coordinate &coor2 = coor1; //引用赋值
Coordinate *pCoor = &coor1; //指向当前地址
coor1.printInfo();
coor2.printInfo();
pCoor->printInfo(); //三者输出的结果是一样的。
const Coordinate &coor2 = coor1;
//对象的常引用
const Coordinate *pCoor = &coor1;
//指向常对象的指针
coor1.printInfo();
coor2.getX(); //× coor2.printInfo();
pCoor->getY(); //× pCoor.printInfo(); 两者都不能使普通的成员函数,只能使用常成员函数。
以下关于常成员函数说法错误的是:
— A、常成员函数的本质是内部使用常this指针。
— B、常成员函数内使用数据成员时,不能改变数据成员的值。
— C、在常成员函数中必须使用常数据成员。
— D、常成员函数不能调用普通的成员函数。
答案:C、常成员函数中可以使用普通的数据成员,但不能改变对象成员的值。
Coordinate *const pCoor = &coor1;
//指向对象的常指针
pCoor->getY();
pCoor = coor2; //错误
pCoor->printInfo();
return 0;
};
//指向常对象的指针是指针类型不可变,而指向对象的常指针是指向对象不可变。
指向常对象的指针(Pointer to a Constant Object):
声明方式类似 const Type* ptr;
通过这个指针,你可以访问对象的成员,但不能修改它们。
用于表示对象是不可变的,防止对象的状态被修改。
指向对象的常指针(Constant Pointer to an Object):
声明方式类似 Type* const ptr;,其中 Type 是对象类型。
通过这个指针,你可以修改对象的成员,但不能更改指针指向的对象。
用于表示指针是不可变的,通常在需要确保指针一直指向同一对象的情况下使用
普通对象能够调用常成员函数,也能够调用普通成员函数。
一个对象可以有多个对象常引用。