Online Book Reader

Home Category

Professional C__ - Marc Gregoire [82]

By Root 1135 0

string name = "heading one";

myCell.setString(name); // Copies name

When the setString() method finishes, inString is destroyed. Because it was only a copy of name, name remains intact.

The copy constructor is also called whenever you return an object from a function or method. In this case, the compiler creates a temporary, unnamed, object through its copy constructor. Chapter 24 explores the impact of temporary objects in more detail. You can avoid the overhead of copy constructors by passing parameters as const references, which will be explained in a later section.

Calling the Copy Constructor Explicitly

You can use the copy constructor explicitly as well. It is often useful to be able to construct one object as an exact copy of another. For example, you might want to create a copy of a SpreadsheetCell object like this:

SpreadsheetCell myCell2(4);

SpreadsheetCell myCell3(myCell2); // myCell3 has the same values as myCell2

Code snippet from SpreadsheetCellCopyCtor\SpreadsheetCellTest.cpp

Passing Objects by Reference

In order to avoid copying objects when you pass them to functions and methods you can declare that the function or method takes a reference to the object. Passing objects by reference is usually more efficient than passing them by value, because only the address of the object is copied, not the entire contents of the object. Additionally, pass-by-reference avoids problems with dynamic memory allocation in objects, which is discussed in Chapter 7.

When you pass an object by reference, the function or method using the object reference could change the original object. When you’re only using pass-by-reference for efficiency, you should preclude this possibility by declaring the object const as well. Here is the SpreadsheetCell class definition in which string objects are passed as const references:

class SpreadsheetCell

{

public:

SpreadsheetCell();

SpreadsheetCell(double initialValue);

SpreadsheetCell(const string& initialValue);

SpreadsheetCell(const SpreadsheetCell& src);

void setValue(double inValue);

double getValue() const;

void setString(const string& inString);

string getString() const;

protected:

string doubleToString(double inValue) const;

double stringToDouble(const string& inString) const;

double mValue;

string mString;

};

Code snippet from SpreadsheetCellCopyCtor\SpreadsheetCell.h

Here is the implementation for setString(). Note that the method body remains the same; only the parameter type is different.

void SpreadsheetCell::setString(const string& inString)

{

mString = inString;

mValue = stringToDouble(mString);

}

Code snippet from SpreadsheetCellCopyCtor\SpreadsheetCell.cpp

For performance reasons, it is best to pass objects by const reference instead of by value.

The SpreadsheetCell methods that return a string still return it by value. Returning a reference to a data member is risky because the reference is valid only as long as the object is “alive.” Once the object is destroyed, the reference is invalid. However, there are sometimes legitimate reasons to return references to data members, as you will see later in this chapter and in subsequent chapters.

Explicitly Defaulted and Deleted Copy Constructor

You can explicitly default or delete a compiler generated copy constructor as follows:

SpreadsheetCell(const SpreadsheetCell& src) = default;

or

SpreadsheetCell(const SpreadsheetCell& src) = delete;

Initializer-List Constructors

An initializer-list constructor is a constructor with std::initializer_list as first argument, without any additional arguments or with additional arguments having default values. Before you can use the std::initializer_list template you need to include the header. The following class demonstrates its use.

class PointSequence

{

public:

PointSequence(initializer_list args)

{

if (args.size() % 2 != 0) {

throw invalid_argument("initializer_list should "

"contain even number of elements.");

}

for (auto iter = args.begin(); iter != args.end(); ++iter)

mVecPoints.push_back(*iter);

Return Main Page Previous Page Next Page

®Online Book Reader