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

it2023-10-07  73

目录

1、Object Pointer & Dynamic Object1. Accessing Object Members via Pointers2. Creating Dynamic Objects on Heap 2、Array of Objects声明方式 3、Passing Objects to Functions1、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,会发生什么情况?

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 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)