面向对象的遇到的类内声明中对private数据的调用

今天翻看C++课件,发现有趣的东西
class CComplex{
public:
void output()
{ cout<<real;
cout<<image; }

double get_real()
{ return real; }
double get_image()
{ return image;}
void reset(double r,double i)
{ real=r; image=i; }

CComplex add( CComplex c2)
{ CComplex c;
c.real=real+c2.real;
c.image=image+c2.image;
return c; }
private:
double real;
double image;
};

当时一开始看到这个时,心想是不是有错误的,因为看到add函数中对新建的对象的私有成员数据进行了直接的调用与赋值(但real、image不是对象的私有成员吗?),而且这也没有用friend友元函数进行声明,会不会是错误的?于是,作为蒟蒻的我上网查找资料,发现原来是要靠咬文嚼字来进行理解的。
解释:在类的成员函数中可以访问本类的私有数据,即使是通过函数参数传入的本类的另一个对象的私有数据,也可以正常访问,即“本类的私有数据”由所有本类的对象的私有数据组成。但是在A类中无法直接访问B类的私有数据,但可以通过友元类实现。
说人话:就是在类中定义的函数对数据成员来说是可以调用的。

函数的参数里面有const限定时,函数的表示形式

当所调用的函数里面有const数据时,其函数要在末尾加上const标识符,暗示函数是常函数
MyString strcpy1( const MyString &s1) ;

上述代码中形参用了const型数据,但是没有在末尾加上const标识符,编译系统会报错。

passing 'const MyString' as 'this' argument discards qualifiers [-fpermissive]

因此正确的操作应为这样子的
MyString strcpy1( const MyString &s1) const;

网上查到的解释是:传进去的const数据是不能够被更改的,当函数没有标识为const并且实际没有对const数据进行改动时,系统还是认为这个函数对const数据进行了改动,因此,在函数的声明以及定义处还是要加上const限定符才可。

关于为什么会有在一个对象中调用其成员函数来生成一个对象,并将其赋值给其它对象的认识

认识:有的创建对象要基于某个对象的数据的话就要在这个对象的数据基础上进行调用。如一本书的id号需要在前一本图书的id+1

关于运算符重载遇到的问题

题目:有两个矩阵a和b,均为n行n列。求两个矩阵之和。重载运算符“+”,使之能用矩阵相加
实现的代码如下:

#include<iostream>
using namespace std;
class Matrix{
private:
int rows,cols;
int **data;

public:
Matrix();
Matrix(int r);
Matrix(const Matrix&);
~Matrix();
// void input();
// void display();
friend Matrix operator+(Matrix &a,Matrix &b);
Matrix& operator =(const Matrix&);
friend istream& operator >>(istream &input,Matrix&a);
friend ostream& operator <<(ostream &output, Matrix &a);
};

istream& operator >>(istream &input,Matrix&a){
cout<<"请输入相应矩阵的值:"<<endl;
for(int i=0;i<a.rows;i++){
for(int j=0;j<a.rows;j++){
input>>a.data[i][j];
}
}
return input;
}

ostream& operator <<(ostream &output, Matrix &a){
output<<"这是相应矩阵的情况:"<<endl;
for(int i=0;i<a.rows;i++){
for(int j=0;j<a.rows;j++){
output<<a.data[i][j]<<' ';
}
output<<endl;
}
return output;
}



Matrix& Matrix::operator = (const Matrix& other){ // 其实就是因为不能通过简单的赋值运算去填充相应的值
if(this != &other){
for(int i=0;i<rows;i++){
delete []data[i];
}
delete []data;

rows = other.rows;
cols = other.cols;
data = new int*[cols];
for(int i=0;i<rows;i++){
data[i] = new int[cols];
for(int j=0;j<rows;j++){
data[i][j] = other.data[i][j];
}
}
}
return *this;
}

Matrix::Matrix(const Matrix& other){
rows = other.rows;
cols = other.cols;
data = new int*[cols];
for(int i=0;i<rows;i++){
data[i] = new int[cols];
for(int j=0;j<rows;j++){
data[i][j] = other.data[i][j]; // 现在仍属于类内部,因此可以直接的引用
}
}
}


Matrix operator+(Matrix &a,Matrix &b){
Matrix c(a.rows);
for(int i=0;i<a.rows;i++){
for(int j=0;j<a.rows;j++){
c.data[i][j] = a.data[i][j] + b.data[i][j];
}
}
return c;
}


Matrix::~Matrix(){
for(int i=0;i<rows;i++){
delete[]data[i];
}

delete[]data;
}

Matrix::Matrix(int r){
rows = r;
cols = r;
data = new int*[rows];
for(int i=0;i<rows;i++){
data[i] = new int[cols];
}
}

Matrix::Matrix(){
rows = 0;
cols = 0;
data = nullptr;
}


int main()
{
cout<<"请输入想要处理的数组大小(正方形):"<<endl;
int n;
cin>>n;
Matrix a(n),b(n),c(n);
cin>>a;
cout<<a;
cin>>b;
cout<<b;
c = a+b;
cout<<c;
return 0;
}

疑问:为什么我要对“=”进行运算符重载操作?
解答:在默认情况下,C++中提供的赋值运算符只能“浅拷贝”一个对象,即将一个对象的地址指向另一个对象的地址。这种简单的赋值运算符并没有为指针类型的数据成员分配新的内存空间。

在本代码中,类Matrix中包含指向二维数组的指针,因此需要在重载赋值运算符时,手动分配新的内存空间并深度拷贝数据,即逐个复制数据成员的值。

否则,如果使用默认的赋值运算符进行赋值,则两个不同的Matrix对象将共享同一块内存空间,容易发生悬挂指针问题和程序崩溃等错误。