天天看点

【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】对象指针、对象数组、函数参数
(2)     Objects Reference as Function Return Value(对象引用作为函数参数)
void print( Circle& c ) {
  /* … */
}
 int main() {
  Circle myCircle(5.0);
  print( myCircle );
  /* … */
}      
【C++ grammar】对象指针、对象数组、函数参数
(3)     Objects Pointer as Function Return Value(对象指针作为函数参数)
// Pass by pointer
void print( Circle* c ) {
  /* … */
}
 int main() {
  Circle myCircle(5.0);
  print( &myCircle );
  /* … *、
}      
【C++ grammar】对象指针、对象数组、函数参数
【C++ grammar】对象指针、对象数组、函数参数

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++中引用和指针的区别

#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;
}      

继续阅读