0
点赞
收藏
分享

微信扫一扫

【C++ grammar】对象指针、对象数组、函数参数


目录

  • ​​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]=     因为声明数组时不能用auto
Circle{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,会发生什么情况?
【C++ grammar】对象指针、对象数组、函数参数_指针

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 );
/* … */
}

【C++ grammar】对象指针、对象数组、函数参数_对象指针_02

(2)     Objects Reference as Function Return Value(对象引用作为函数参数)
void print( Circle& c ) {
/* … */
}
int main() {
Circle myCircle(5.0);
print( myCircle );
/* … */
}

【C++ grammar】对象指针、对象数组、函数参数_指针_03

(3)     Objects Pointer as Function Return Value(对象指针作为函数参数)
// Pass by pointer
void print( Circle* c ) {
/* … */
}
int main() {
Circle myCircle(5.0);
print( &myCircle );
/* … *、
}

【C++ grammar】对象指针、对象数组、函数参数_函数返回值_04
【C++ grammar】对象指针、对象数组、函数参数_指针_05

2. Objects as Function Return Value(对象作为函数返回值)

// class Object { ... };
Object f ( /*函数形参*/ ){
// Do something
return Object(args);
}
// main() {
Object o = f ( /*实参*/ );
f( /*实参*/ ).memberFunction();

3. Objects Pointer as Function Return Value(对象指针作为函数返回值)

// class Object { ... };
Object* f ( Object* p, /*其它形参*/ ){
// Do something
return 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 something
return o;
}
}
可行的用法2
// class Object { ... };
Object& f ( Object& p, /*其它形参*/ ){
// Do something
return 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。


举报

相关推荐

0 条评论