C++类对象作为函数参数传递详解
例如,以下函数具有一个接收 Rectangle 对象的形参:
void displayRectangle(Rectangle r)
{
cout << "Length = " << r.getLength() << endl;
cout << "Width = " << r.getWidth() << endl;
cout << "Area = " << r.getArea() << endl; '
}
Rectangle box(15, 10);
displayRectangle(box);
Length = 15
Width = 10
Area = 150
下面的程序说明了这一点:
#include <iostream> #include <iomanip> #include <string> using namespace std; class InventoryItem { private: int partNum; // Part number string description; // Item description int onHand; // Units on hand double price; // Unit price public: void storeInfo(int p, string d, int oH, double cost); // Prototype int getPartNum() { return partNum; } string getDescription() { return description; } int getOnHand() { return onHand; } double getPrice() { return price; } }; void InventoryItem::storeInfo(int p, string d, int oH, double cost) { partNum = p; description = d; onHand = oH; price = cost; } //Function prototypes for client program void storeValues (InventoryItem&);// Receives an object by reference void showValues (InventoryItem); // Receives an object by value int main() { InventoryItem part; // part is an Inventoryltem object storeValues(part); showValues(part); return 0; } void storeValues(InventoryItem &item) { int partNum; // Local variables to hold user input string description; int qty; double price; // Get the data from the user cout << "Enter data for the new part number \n"; cout << "Part number: "; cin >> partNum; cout << "Description: "; cin.get(); getline (cin, description); cout << "Quantity on hand: "; cin >> qty; cout << "Unit price: "; cin >> price; item.storeInfo(partNum, description, qty, price); } void showValues(InventoryItem item) { cout << fixed << showpoint << setprecision(2) << endl; cout << "Part Number : " << item.getPartNum() << endl; cout << "Description : " << item.getDescription () << endl; cout << "Units On Hand: " << item.getOnHand () << endl; cout << "Price : $" << item.getPrice() << endl; }程序输出结果:
Enter data for the new part number
Part number: 175
Description: Hammer
Quantity on hand: 12
Unit price: 7.49
Part Number : 175
Description : Hammer
Units On Hand: 12
Price : $7.49
程序中还可以看到,Inventoryltem 类声明出现在 storeValues 和 showValues 函数的原型之前,这一点很重要,因为这两个函数都有一个 Inventoryltem 对象作为形参,所以编译器在遇到任何引用它的语句之前,必须知道 Inventoryltem 是什么,否则就会发生错误。
常量引用形参
在上面的程序中,InventoryItem 对象按值传递给 showValues 函数。但是,按值传递对象需要复制所有对象成员的副本,这可能会减慢程序的执行时间,如果对象有很多成员,则更是如此。另一方面,当按引用传递对象时,由于该函数可以访问原始对象,而不必进行任何复制,所以它比通过值传递更快,正因为如此,一般更愿意按引用传递对象。但是,按引用传递对象有一个缺点,因为该函数可以访问原始对象,所以它可以调用其设置器函数更改对象成员数据。这就是为什么当程序员想要保护对象的内容时,通常不会按引用传递变量。
幸运的是这个问题有解决办法。为了保护对象让它作为实参传递,而又不必复制副本,可以将它作为常量引用进行传递,这意味着原始对象作为引用被传递给了函数,但是它不能调用任何设置器函数或更改对象的成员数据,它只能调用自己被指定为常量函数的访问器函数。
要将形参声明为常量引用形参,必须将关键字 const 放在函数原型和函数头的形参列表中。对照上面程序中的 showValues 函数的函数原型和函数头,如果将它改为使用常量引用形参,则语句如下:
void showValues (const InventoryItem&) //函数原型
void showValues (const InventoryItem &item) // 函数头
double getPrice() const
如果 showValues 尝试调用任何其他 InventoryItem 函数,则会发生编译器错误。请注意,当 showValues 被修改为具有常量引用形参时,只有函数原型和函数头被更改为包含关键字 const。showValues 函数的主体和对 showValues 的调用不会改变。从函数返回一个对象
正如函数可以编写为返回一个 int、double 或其他数据类型一样,它们也可以设计为返回一个对象。事实上,当以前从函数返回一个字符串时,就已经是在这样做了,因为字符串就是一个对象。当函数返回一个对象时,它通常会创建该类的局部实例,设置其数据成员,然后返回它。
以下仍以上面程序为例,说明如何在 storeValues 函数中创建 InventoryItem 对象,然后返回到调用函数。请注意,这个新版本的 storeValues 函数不接收任何实参,它的返回类型现在是 InventoryItem 而不是 void。
InventoryItem storeValues() { InventoryItem templtem; // Inventoryltem 局部对象 int partNum; //存储用户输入的局部变量 string description; int qty; double price; //在此编写获取用户输入的代码. //将数据保存到InventoryItem对象并返回它 tempItem.storeInfo(partNum, description, qty, price); return tempItem; }main 函数随后应创建 part 语句,如下所示:
InventoryItem part = storeValues();
下面的程序修改了之前的程序,以纳入刚才讨论的技术。以前名为 storeValues 的函数被重命名为 createItem,因为它现在会创建一个名为 InventoryItem 的对象并将其返回给 main。showValues 函数现在接收 part 作为常量引用,而不是像以前一样按值传递它。#include <iostream> #include <iomanip> #include <string> using namespace std; class InventoryItem { private: int partNum; // Part number string description; // Item description int onHand; // Units on hand double price; // Unit price public: void storeInfo (int p, string d, int oH, double cost);// Prototype int getPartNum () const { return partNum; } string getDescription() const { return description; } int getOnHand() const { return onHand; } double getPrice() const { return price; } }; void InventoryItem::storeInfo(int p, string d, int oH, double cost) { partNum = p; description = d; onHand = oH; price = cost; } InventoryItem createItem(); // Returns an Inventoryltem object void showValues (const InventoryItem&); int main() { InventoryItem part = createItem (); showValues(part); return 0; } InventoryItem createItem() { InventoryItem tempItem;// Local Inventoryltem object int partNum; // Local variables to hold user input string description; int qty; double price; //Get the data from the user cout << "Enter data for the new part number \n"; cout << "Part number: "; cin >> partNum; cout << "Description:"; cin.get(); getline(cin, description); cout << "Quantity on hand: "; cin >> qty; cout << "Unit price: "; cin >> price; tempItem.storeInfo(partNum, description, qty, price); return tempItem; } void showValues(const InventoryItem &item) { cout << fixed << showpoint << setprecision(2) << endl; cout << "Part Number : " << item.getPartNum() << endl; cout << "Description : " << item.getDescription () << endl; cout << "Units On Hand: " << item.getOnHand () << endl; cout << "Price : $"<< item.getPrice () << endl; }程序输出结果:
Enter data for the new part number
Part number: 175
Description:Hammer
Quantity on hand: 12
Unit price: 7.49
Part Number : 175
Description : Hammer
Units On Hand: 12
Price : $7.49
所有教程
- C语言入门
- C语言编译器
- C语言项目案例
- 数据结构
- C++
- STL
- C++11
- socket
- GCC
- GDB
- Makefile
- OpenCV
- Qt教程
- Unity 3D
- UE4
- 游戏引擎
- Python
- Python并发编程
- TensorFlow
- Django
- NumPy
- Linux
- Shell
- Java教程
- 设计模式
- Java Swing
- Servlet
- JSP教程
- Struts2
- Maven
- Spring
- Spring MVC
- Spring Boot
- Spring Cloud
- Hibernate
- Mybatis
- MySQL教程
- MySQL函数
- NoSQL
- Redis
- MongoDB
- HBase
- Go语言
- C#
- MATLAB
- JavaScript
- Bootstrap
- HTML
- CSS教程
- PHP
- 汇编语言
- TCP/IP
- vi命令
- Android教程
- 区块链
- Docker
- 大数据
- 云计算