C++类成员返回对象
主要内容
1.类成员函数临时对象
2.类成员函数返回持久对象
3.类成员函数返回指针
案例详解
//类成员函数返回类的对象
#include<iostream>
#include<string>
using namespace std;
class A {
public:
A() {
x = 50;
for(int i=0; i<10; i++) {
arr[i]=0;
}
str1 = "无参构造str1";
str2="无参构造str2";
cout<<"无参构造调用"<<endl;
}
void setArr() {
for(int i=0; i<10; i++) {
arr[i]=i+100;
}
}
A(int x1,string s1,string s2) {
x = x1;
str1 = s1;
str2 = s2;
cout<<"有参构造调用"<<endl;
}
string getStr1() {
return str1;
}
string getStr2() {
return str2;
}
// 返回指针对象
A *Add_ptr(A &p) {
cout<<"成员函数调用构造函数:"<<endl;
A *temp=new A;
temp->x = p.x+x;
temp->str1 = p.str1+str1;
temp->str2=p.str2+str2;
for(int i=0; i<10; i++) {
temp->arr[i]=p.arr[i]+arr[i];
}
return temp;
}
// 复制构造函数
A(const A &p) {
x = p.x;
str1 = p.str1;
str2 = p.str2;
for(int i=0; i<10; i++) {
arr[i]=p.arr[i];
}
cout<<"复制构造调用"<<endl;
}
// 返回是临时对象,临时对象使用A s = p.Add(q);
// 必须使用复制构造函数 A(const A &p),使返回的临时对象转为持久对象 s,从而具有正常功能
A Add(A &p) {
A temp;
temp.x = x+p.x;
temp.str1=str1+p.str1;
temp.str2 = str2+p.str2;
for(int i=0; i<10; i++) {
temp.arr[i]=p.arr[i]+arr[i];
}
return temp;
}
// 返回的不再是临时对象,而是一个正常的可更改内容的对象
A &Add_1(A &p) {
A *ptr = new A;
ptr->x = x+p.x;
ptr->str1=str1+ptr->str1;
ptr->str2 = str2+ptr->str2;
for(int i=0; i<10; i++) {
ptr->arr[i]=ptr->arr[i]+arr[i];
}
return *ptr;
}
// 返回当前对象的引用
A &Add_test(A &p){
x += p.x;
str1 += p.str1;
str2 += p.str2;
for(int i=0; i<10; i++) {
arr[i] += p.arr[i];
}
return *this;
}
// 使用引用对象做出一些修改
void AddTest(A &p){
p.x += x;
p.str1 += str1;
p.str2 += str2;
for(int i=0; i<10; i++) {
p.arr[i] += arr[i];
}
}
A getA() {
A p(11,"str1","str2");
for(int i=0; i<10; i++) {
p.arr[i]=0;
}
return p;
}
// 赋值运算
A &operator=(A &p) {
cout<<"赋值运算符重载调用"<<endl;
x = p.x;
str1 = p.str1;
str2 = p.str2;
return *this;
}
// 输出运算
friend ostream &operator<<(ostream &out,A &p) {
out<<"输出运算符重载调用"<<endl;
out<<p.x<<endl<<p.str1<<endl<<p.str2<<endl;
for(int i=0; i<10; i++) {
out<<p.arr[i]<<"\t";
}
out<<endl;
return out;
}
void print() {
cout<<"print输出"<<endl;
cout<<x<<endl<<str1<<endl<<str2<<endl;
for(int i=0; i<10; i++) {
cout<<arr[i]<<"\t";
}
cout<<endl;
}
private :
int x;
int arr[10];
string str1;
string str2;
};
//使用一
// 局部对象
void test_1() {
// 1.成员函数p.Add(q)返回一个新对象,
// 当已存在赋值构造函数 A(A &p) 时,
// 用一个新的对象 s 来接受 该返回对象,则会报错
cout<<"使用一:"<<endl;
A p;
A q;
p.setArr();
q.setArr();
// 2.若显式声明复制构造函数A::A(A &p),则A s = p.Add(q);会报错的原因:
// (1).报错信息:[Note] no known conversion for argument 1 from 'A' to 'A&'
// 可见A s = p.Add(q) 返回的是临时对象,不能进行更改,所以也不能被 A::A(A &p)调用
// (2).当没有显示复制构造函数A::A(A &p)时却没有问题:
// 这是因为C++默认的复制构造函数是A::A(const A &p),即参数p是不可更改的,而我们自定义的赋值构造函数A::A(A &p)参数p是可更改的
// 解决办法:
// (1)一种是声明赋值构造函数为A::A(const A &p)
// (2)另一种继续使用 A::A(A &p),但要使用 A s = p.Add_1(q); 此时返回的对象是持久对象
// 可用
// A s = p.Add_1(q);
// 可用
A s = p.Add(q);
cout<<s;
// 这样却可以
p.Add(q).print();
cout<<endl;
}
//使用二
// 局部指针对象
void test_2() {
cout<<"使用二:"<<endl;
A p;
A q;
p.setArr();
q.setArr();
// 尝试调用指针对象
A *ptr = p.Add_ptr(q);
cout<<*ptr;
cout<<ptr->getStr1()<<endl;
cout<<endl;
// 分配过空间需要删除
delete ptr;
}
// 使用三
//
void test_3() {
cout<<"使用三:"<<endl;
A p;
// 调用复制构造函数
A q = p;
A s;
// 调用赋值运算符重载
s = q;
s.setArr();
cout<<s<<endl;
}
// 使用四
// 对象的引用
void test_4(){
cout<<"使用四:"<<endl;
A p;
A q;
p.setArr();
q.setArr();
// 调用 A &Add_test(A &p)
A r = p.Add_test(q);
// 返回时调用了复制构造函数
cout<<r<<endl;
}
// 引用修改
void test_5(){
A p;
A q;
p.setArr();
q.setArr();
// 对 q 做出修改
p.AddTest(q);
cout<<q<<endl;
}
int main() {
test_1();
// test_2();
// test_3();
// test_4();
// test_5();
}