目录
- 1、Object Pointer & Dynamic Object
- 1. Accessing Object Members via Pointers
- 2. Creating Dynamic Objects on Heap
- 2、Array of Objects
- 声明方式
- 3、Passing Objects to Functions
- 1、Objects as Function Arguments (对象作为函数参数)
- 2. Objects as Function Return Value(对象作为函数返回值)
- 3. Objects Pointer as Function Return Value(对象指针作为函数返回值)
- 4. Objects Reference as Function Return Value(对象引用作为函数返回值)
1、Object Pointer & Dynamic Object
1. Accessing Object Members via Pointers
Object pointers can be assigned new object names
Arrow operator -> : Using pointer to access object members
Circle circle1;
Circle* pCircle = &circle1;
cout << "The radius is " << (*pCircle).radius << endl;
cout << "The area is " << (*pCircle).getArea() << endl;
(*pCircle).radius = 5.5;
cout << "The radius is " << pCircle->radius << endl;
cout << "The area is " << pCircle->getArea() << endl;
2. Creating Dynamic Objects on Heap
Object declared in a function is created in the stack, When the function returns, the object is destroyed 。
To retain the object, you may create it dynamically on the heap using the new operator.
Circle *pCircle1 = new Circle{}; //用无参构造函数创建对象
Circle *pCircle2 = new Circle{5.9}; //用有参构造函数创建对象
//程序结束时,动态对象会被销毁,或者
delete pObject; //用delete显式销毁
2、Array of Objects
声明方式
1、
Circle ca1[10];
2、用匿名对象构成的列表初始化数组
Circle ca2[3] = { // 注意:不可以写成: auto ca2[3]= 因为声明数组时不能用autoCircle{3}, Circle{ }, Circle{5} };
3、声明方式3
用C++11列表初始化,列表成员为隐式构造的匿名对象
Circle ca3[3] { 3.1, {}, 5 };
Circle ca4[3] = { 3.1, {}, 5 };
4、 声明方式4
用new在堆区生成对象数组
auto* p1 = new Circle[3];
auto p2 = new Circle[3]{ 3.1, {}, 5 };
//p1 p2都是指针,*在auto的时候会自动处理
delete [] p1;
delete [] p2;
p1 = p2 = nullptr;
上述代码第4行若是改为 delete [] p1,会发生什么情况?
3、Passing Objects to Functions
1、Objects as Function Arguments (对象作为函数参数)
You can pass objects by value or by reference. (对象作为函数参数,可以按值传递也可以按引用传递)
(1) Objects as Function Return Value(对象作为函数参数)
// Pass by value
void print( Circle c ) {/* … */
}int main() {Circle myCircle(5.0);print( myCircle );/* … */
}
(2) Objects Reference as Function Return Value(对象引用作为函数参数)
void print( Circle& c ) {/* … */
}int main() {Circle myCircle(5.0);print( myCircle );/* … */
}
(3) Objects Pointer as Function Return Value(对象指针作为函数参数)
// Pass by pointer
void print( Circle* c ) {/* … */
}int main() {Circle myCircle(5.0);print( &myCircle );/* … *、
}
2. Objects as Function Return Value(对象作为函数返回值)
// class Object { ... };
Object f ( /*函数形参*/ ){// Do somethingreturn Object(args);
}
// main() {
Object o = f ( /*实参*/ );
f( /*实参*/ ).memberFunction();
3. Objects Pointer as Function Return Value(对象指针作为函数返回值)
// class Object { ... };
Object* f ( Object* p, /*其它形参*/ ){// Do somethingreturn p;
}
// main() {
Object* o = f ( /*实参*/ );
// 不应该delete o
尽可能用const修饰函数返回值类型和参数除非你有特别的目的(使用移动语义等)。
const Object* f(const Object* p, /* 其它参数 */) { }
4. Objects Reference as Function Return Value(对象引用作为函数返回值)
// class Object { ... };
class X {Object o;Object f( /*实参*/ ){// Do somethingreturn o;}
}
可行的用法2
// class Object { ... };
Object& f ( Object& p, /*其它形参*/ ){// Do somethingreturn p;
}
// main() {
auto& o = f ( /*实参*/ );
f( /*实参*/ ).memberFunction();
用const修饰引用类型的函数返回值,除非你有特别目的(比如使用移动语义)
const Object& f( /* args */) { }
关于指针与引用的差别,请看这篇文章:
C++中引用和指针的区别
大概来讲:
1、因此如果你有一个变量是用于指向另一个对象,但是它可能为空,这时你应该使用指针;如果变量总是指向一个对象,i.e.,你的设计不允许变量为空,这时你应该使用引用。
2、引用不可以改变指向,但是指针可以改变指向,而指向其它对象。
#include<iostream>
using namespace std;
int main(int argc,char** argv)
{int i=10;int& ref=i;ref++;cout<<"i="<<i<<endl;cout<<"ref="<<ref<<endl;int j=20;ref=j;ref++;cout<<"i="<<i<<endl;cout<<"ref="<<ref<<endl;cout<<"j="<<j<<endl;return 0;
}
对ref的++操作是直接反应到所指变量之上,对引用变量ref重新赋值"ref=j",并不会改变ref的指向,它仍然指向的是i,而不是j。理所当然,这时对ref进行++操作不会影响到j。