Using References in const Methods
Let's say I have a class like this:
class LinkedList
{
struct Node
{
int StoredValue;
// ...
};
Node& GetNodeReference(std::size_t Index)
{
// ...
return NodeReference;
}
public:
int Get(std::size_t Index) const
{
return GetNodeReference(Index).StoredValue;
}
};
This won't compile because the const
method Get
uses GetNodeRef开发者_如何学Goerence
, which cannot be const
because it returns a reference.
How can I work around this?
I'm not sure what you're trying to achieve, but you could provide two overloads of GetNodeReference
:
Node& GetNodeReference(std::size_t Index)
{
// ...
return NodeReference;
}
const Node& GetNodeReference(std::size_t Index) const
{
// ...
return NodeReference;
}
Note that the second overload has two const
modifers, one at the beginning of the line for the return type and one at the end of the line for the implicitly passed *this
object.
To avoid code repetition, you can implement the non-const overload based on the const overload:
const Node& GetNodeReference(std::size_t Index) const
{
// ...
return NodeReference;
}
Node& GetNodeReference(std::size_t Index)
{
return const_cast<Node&>(static_cast<const LinkedList&>(*this).getNodeReference(Index));
}
This technique is discussed in Item 3 of Effective C++ by Scott Meyers.
Don't implement an indexed Get
function for lists at all. It will be WAY too easy for a new developer to come in and use it in a loop, turning a linear interation into a polynomial iteration.
If you need such a capability, make a free-function that uses the builtin iterators of the list in conjunction with say std::advance
to get the node you want.
If you absolutely need the member function, then the normal approach is the one suggested by @FredOverflow and use overloads (quote his code):
const Node& GetNodeReference(std::size_t Index) const
{
// ...
return NodeReference;
}
Node& GetNodeReference(std::size_t Index)
{
return const_cast<Node&>(static_cast<const LinkedList&>(*this).getNodeReference(Index));
}
How about this?
class LinkedList {
private:
struct Node { int StoredValue; // ... }; Node NodeReference; const Node* const GetNodeReference(std::size_t Index) const { return &NodeReference; }
public:
int Get(std::size_t Index) const { const Node *const node = GetNodeReference(Index); return node->StoredValue; }
};
Edit:
As you can read in the comments
const Node* const GetNodeReference(std::size_t Index) const () ...
should be changed to:
const Node* GetNodeReference(std::size_t Index) const () ...
I suggest:
class LinkedList {
private:
struct Node { int StoredValue; // ... }; Node NodeReference; const Node& GetNodeReference(std::size_t Index) const { return NodeReference; }
public:
int Get(std::size_t Index) const { const Node node = GetNodeReference(Index); return node.StoredValue; }
};
精彩评论