I have a Node class defined like this (this is a minimal version):
class Node {
private:
std::vector <const Node*> leaves;
public:
Node* getLeaf(int i);
}
In other words, I want getLeaf to return a pointer to an element of the vector "leaves"
I tried defining getLeaf like so
Node* Node::getLeaf(int i){
return leaves[i];
}
Ok, so I know I'm screwing the constness up. I've tried variations of const modifiers in my function declarations / definitions to no luck. Someone please help :)
const is a promise to not change.
You declare a vector of pointers to const nodes. That's a promise to not change any Node via these pointers.
The getLeaf function can't very well then return a pointer to non-const node, because then the caller can do anything with the node.
So you have to make either the same promise both places, or don't make any such promise.
Another matter is whether getLeaf itself should be const (it probably should, it makes sense to let it promise not to change the object), and a second other matter is whether get makes sense as a prefix in C++ (usually not, it's just needless verbosity, while in Java there are tools that can make good use of such of prefix), I'd just call it node.
Related
I have a member function which is declared const and modifies data via a pointer. This seems misleading. Should I remove the const keyword?
I would like to know how others handle this situation in their code. Do people just add a comment to clarify what is going on? Do they not add the const keyword to the member function? Maybe something else completely?
Any advice is appreciated.
You have essentially two choices:
Deep constness:
class Foo
{
T * ptr;
public:
T & operator*() { return *ptr; }
T const & operator*() const { return *ptr; }
T * operator->() { return ptr; }
T const * operator->() const { return ptr; }
};
Shallow constness:
class Foo
{
T * ptr;
public:
T & operator*() const { return *ptr; }
T * operator->() const { return ptr; }
};
It's really up to you, and to the purpose of your class. If the class is a smart pointer, it would seem reasonable to have shallow constness semantics, since the class is supposed to be as similar to a raw pointer as possible (and you can of course have a constant raw pointer to a non-constant pointee).
Otherwise, you should ask yourself why you would be exposing access to a member pointer object at all. It's certainly possible that you want to give mutable access via constant references to your class, but I imagine those are special and rare circumstances. There shouldn't really be that many raw pointers in your code in the first place. Returning a deeply-const reference by dereferencing a pointer should be fine, but usually in better encapsulated "getter" functions which hide the fact that there is a pointer inside your class, like T const & get() const { return *ptr; }.
Generally, yes. Its deceptive to modify something you are declaring constant, even though you can do it.
If someone uses your code and sees const, they expect const. Modification, even though sensible to you, might cause them severe problems -- even crashing a program.
Consider a std::vector<Blah> member versus a Blah* member used to implement a dynamic array. Most often it makes sense to replace the latter with the former. With the Blah* memeber a const method is allowed to modify the data in the array, while with the std::vector<Blah> member the const method is not allowed to modify data there.
Also consider a matrix class with an indexing method that returns a proxy that allows assignment to an element. Assigning via the proxy changes the matrix, not the proxy object itself. Thus, the proxy object’s assignment operator can be (and should be) const, in order to impose the most constraints possible on its effect, while its primary job is to modify things.
That’s another example that the design level is different from the coding level.
In the first example, with a member array, const was all about expressing a design level constraint, but in the second example, with the assignment proxy, const was all about expressing a coding level constraint.
These usages are not incompatible, however. The key idea is to provide a reader of the code with as many constraints as possible (because that greatly reduces how many varying things that must be considered to understand or deal with the code). Upshot: add const wherever you practically can.
My problem is the use of const_cast<>. I have a class which inherits from vector. Now in one of its member functions when I use this->begin(), this being a const pointer, it returns a constant iterator but I want to obtain a non-const iterator. The code looks something like ...
class xyz : private std::vector<//something>
{
public:
xyz();
void doSomething();
}
void doSomething()
{
xyz::iterator it;
it = this->begin();
*it.insert(something); //here is the problem and this where I need to use const_cast
// and in a lot more places
}
In the above function, since this->begin() returns a const iterator, I am forced to use a constant iterator and do a typecasting whenever I need to insert an element.
I thought of using const_cast at this->begin() but my friend told me that it is a bad idea to remove the constness of the this pointer. If it is so, then what is the way around?
If the vector is part of the state of the class, either as a member or
as a base (although it's really bad practice to publicly inherit from
vector), then a const member function should not modify it. If the
vector is part of the state, and a function modifies it, the function
should not be const.
Generally. There are special cases where, for example, the vector
represents cached state, that is logically calculated, but whose
calculation is expensive. In such cases, you can make the vector a
mutable member. But do be sure that the vector really doesn't represent
"observable state".
And finally, the code you post doesn't seem to have anything to do with
the problem. For starters, the only function is non-const. And the
code won't compile, for several reasons (use of this in a non-member
function, invocation of a member function insert on an iterator, which
doesn't have such a member, etc.).
My professor has asks us to reimplement all of the LinkedList functions from scratch. However, since this is a beginner class, he has put a few stipulations on it. Below is the full assignment:
"For list, you must implement everything but get_allocator. For all functions that take an "iterator" as an argument, instead accept a node class. For all functions that return an iterator, return a node instead."
Since LinkedList use pointers, I am not sure how to do return a node without just returning a pointer. What would be the syntax for returning a node pointed to by a pointer called *current?
I am also unsure how to format the functions. For example, what would be the syntax for changing the following function to accept a node class and then return a node(i don't need the code for the function, just how to accept a node and return a node class):
iterator insert (iterator position, const int&x)
"For list, you must implement everything but get_allocator. For all
functions that take an "iterator" as an argument, instead accept a
node class. For all functions that return an iterator, return a node
instead."
Since LinkedList use pointers, I am not sure how to do return a node
without just returning a pointer. What would be the syntax for
returning a node pointed to by a pointer called *current?
I think your professor is talking about accepting and returning pointers (or references) to nodes, not node values (copying nodes). I can say that with some degree of confidence because that's the only way to preserve the underlying semantics of std::list with a one-to-one translation of iterators to nodes (node pointers).
However, if your nodes are just mere aggregates storing pointers themselves and don't try to do any memory management, then you can get away with copying them around, but I'd go with pointers if in doubt.
So, something like this:
iterator insert(iterator position, const T& val)
{
...
}
Would look like this for your practice homework:
LinkedListNode* insert(LinkedListNode* position, const T& val)
{
...
}
If you aren't using templates and can just make it a list of integers or whatever:
LinkedListNode* insert(LinkedListNode* position, int val)
{
...
}
Hope later your professor will make you appreciate the power of the iterator-based versions as those allow you to write function templates that work not only on linked lists but any kind of sequence, for example.
I think you shouldn`t use pointers. Try to use reference or iterators?
To dereference a pointer, use the * operator. For example, if you have a valid pointer-to-int, and you want access to use the int that it points to:
*pointer_to_int = 5;
j = *pointer_to_int / 3;
and so forth. Similarly, if you want to pass the value of the pointed-to-int to a function,
k = SomeFunction(*pointer_to_int, 12, foo);
or return it from a function:
int Function() {
return *pointer_to_int;
}
You can use the syntax *pointer anywhere you might otherwise say, variable.
The syntax for declaring functions that return a type doesn't change based on the type. Suppose you have some function that returns an int:
int MyFunction() { return my_int; }
Or, if it returned an iterator:
iterator MyFunction() { return my_iterator; }
Or, if it returned an Apple:
Apple MyFunction() { return my_apple; }
You see, you just need to replace the name of the return type with whatever type you are returning.
Hopefully, you can see now how to declare a function that returns a node object, and how to return a node object, given that you only have a pointer_to_node.
The following is said to be better than having First() and Second() as public members. I believe this is nearly as bad.
// Example 17-3(b): Proper encapsulation, initially with inline accessors. Later
// in life, these might grow into nontrivial functions if needed; if not, then not.
template<class T, class U>
class Couple {
public:
Couple() : deleted_(false) { }
void MarkDeleted() { deleted_ = true; }
bool IsDeleted() { return deleted_; }
private:
T first_;
U second_;
bool deleted_;
T& First() { return first_; }
U& Second() { return second_; }
};
If you're giving a way to access a private variable outside of the class then what's the point? Shouldn't the functions be
T First(); void(or T) First(const T&)
There are several reasons why returning references (or pointers) to the internals of a class are bad. Starting with (what I consider to be) the most important:
Encapsulation is breached: you leak an implementation detail, which means that you can no longer alter your class internals as you wish. If you decided not to store first_ for example, but to compute it on the fly, how would you return a reference to it ? You cannot, thus you're stuck.
Invariant are no longer sustainable (in case of non-const reference): anybody may access and modify the attribute referred to at will, thus you cannot "monitor" its changes. It means that you cannot maintain an invariant of which this attribute is part. Essentially, your class is turning into a blob.
Lifetime issues spring up: it's easy to keep a reference or pointer to the attribute after the original object they belong to ceased to exist. This is of course undefined behavior. Most compilers will attempt to warn about keeping references to objects on the stack, for example, but I know of no compiler that managed to produce such warnings for references returned by functions or methods: you're on your own.
As such, it is usually better not to give away references or pointers to attributes. Not even const ones!
For small values, it is generally sufficient to pass them by copy (both in and out), especially now with move semantics (on the way in).
For larger values, it really depends on the situation, sometimes a Proxy might alleviate your troubles.
Finally, note that for some classes, having public members is not so bad. What would be the point of encapsulating the members of a pair ? When you find yourself writing a class that is no more than a collection of attributes (no invariant whatsoever), then instead of getting all OO on us and writing a getter/setter pair for each of them, consider making them public instead.
If template types T and U are big structures then return by value is costly. However you are correct that returning by reference is equivalent to giving access to a private variable. To solve both issues, make them const references:
const T& First() const { return first_; }
const U& Second() const { return second_; }
P.S. Also, it's a bad practice to keep variables uninitialized inside constructor, when there is no setter method. It seems that in the original code, First() and Second() are wrappers over first_ and second_ which were meant for read/write both.
The answer depends on what one is trying to do. Returning references are a convenient way to facilitate mutation of data structures. A good example is the stl map. It returns reference to the element i.e.
std::map<int,std::string> a;
a[1] = 1;
nothing to stop you from doing
auto & aref = a[1];
Is it necessarily a bad practice? I would not think so. I would say, if you can do without it do so. If it makes life more convenient and efficient use it and be aware of what you are doing.
I would like to know a good syntax for C++ getters and setters.
private:
YourClass *pMember;
the setter is easy I guess:
void Member(YourClass *value){
this->pMember = value; // forget about deleting etc
}
and the getter?
should I use references or const pointers?
example:
YourClass &Member(){
return *this->pMember;
}
or
YourClass *Member() const{
return this->member;
}
whats the difference between them?
Thanks,
Joe
EDIT:
sorry, I will edit my question... I know about references and pointers, I was asking about references and const pointers, as getters, what would be the difference between them in my code, like in hte future, what shoud I expect to lose if I go a way or another...
so I guess I will use const pointers instead of references
const pointers can't be delete or setted, right?
As a general law:
If NULL is a valid parameter or return value, use pointers.
If NULL is NOT a valid parameter or return value, use references.
So if the setter should possibly be called with NULL, use a pointer as a parameter. Otherwise use a reference.
If it's valid to call the getter of a object containing a NULL pointer, it should return a pointer. If such a case is an illegal invariant, the return value should be a reference. The getter then should throw a exception, if the member variable is NULL.
Your code looks a great deal as if you're accustomed to a different language -- in C++ using this->x (for one example) is relatively unusual. When the code is at all well written, so is using an accessor or mutator.
Though I'm fairly unusual in this particular respect, I'll go on record (yet again) as saying that forcing client code to use an accessor or mutator directly is a bad idea. If you honestly have a situation where it makes sense for client code to manipulate a value in your object, then the client code should use normal assignment to read and/or write that value.
When/if you need to control what value is assigned, operator overloading lets you take that control without forcing ugly get/set syntax on the client code. Specifically, what you want is a proxy class (or class template). Just for one example, one of the most common situations where people want get/set functions is something like a number that's supposed to be restricted to some particular range. The setXXX checks the new value for being in range, and the getXXX returns the value.
If you want that, a (fairly) simple template can do the job much more cleanly:
template <class T, class less=std::less<T> >
class bounded {
const T lower_, upper_;
T val_;
bool check(T const &value) {
return less()(value, lower_) || less()(upper_, value);
}
void assign(T const &value) {
if (check(value))
throw std::domain_error("Out of Range");
val_ = value;
}
public:
bounded(T const &lower, T const &upper)
: lower_(lower), upper_(upper) {}
bounded(bounded const &init)
: lower_(init.lower), upper_(init.upper)
{
assign(init);
}
bounded &operator=(T const &v) { assign(v); return *this; }
operator T() const { return val_; }
friend std::istream &operator>>(std::istream &is, bounded &b) {
T temp;
is >> temp;
if (b.check(temp))
is.setstate(std::ios::failbit);
else
b.val_ = temp;
return is;
}
};
This also makes the code much closer to self documenting -- for example, when you declare an object like: bounded<int>(1, 1024);, it's immediately apparent that the intent is an integer in the range of 1 to 1024. The only part somebody might find open to question is whether 1 and/or 1024 is included in the range. This is considerably different from defining an int in the class, and expecting everybody who ever looks at the class to realize that they're supposed to use the setXXX to enforce some (at that point unknown) set of bounds on the values that can be assigned.
When you embed one of these in a class, you make it a public variable, and the range is still enforced. In the client code, there's no real argument over syntax -- you're just assigning to a public variable, like you would any other -- with the minor detail that attempting to assign a value that's out of range will throw an exception. In theory, the class should probably take a policy template-parameter to specify exactly what it does in that case, but I've never had a real reason to bother with that.
The best thing is to provide a real OO interface to the client that hides implementaton details. Getters and Setters are not OO.
As others have said, use pointers if null is a possibility.
In most cases, I prefer to use references when possible. Personally, in my code, I like to use the distinction between pointers and references to signal ownership. I think of calls with references as "loaning" an object to another function or class. The original class that passed or returned the reference still owns it, and is responsible for its creation, maintenance and clean up. When my code passes a non-const pointer, on the other hand, it usually means that there's some kind of transfer or sharing of ownership going on, with all the responsibilities that entails.
(And yes, I usually use smart pointers. Those are akin to references in my mind. I'm talking about lower level code than that here.)
whats the difference between them?
The reference is an alias of the thing(it is the thing*). A pointer is the address of the thing. If there's a chance that what's pointed to won't be there, then you probably don't want to return references. References tell the caller "I'm going to give you an alias that will exist when I return it to you". In fact there's really no way to check the reference to see if what's underlying is valid.
With the pointer, semantically, you are implying that the caller may wish to check to see if Member exists before using it. Ussually this is done with a NULL check.
Ultimately there's no "right" answer. It depends on the class's contract and if the caller will/should/wants to check whether "Member" is still around.
The short answer is pointers for things that can be pointed elsewhere and references for "unseated" aliases.
In addition to the other answers, if you choose references for the getter don't write it like in your example:
YourClass &Member(){
return *this->pMember;
}
Your getter actually allows setting, as in instance->Member() = YourClass(); and thus bypassing your setter. This might not be allowed if YourClass is noncopyable, but is still another thing to have in mind. Another drawback is the getter is not const.
Instead, write your getter like this:
const YourClass &Member() const {
return *this->pMember;
}
+1 on questioning the use of setters and getters. If you must use them and have the possibility of nulls consider using boost::shared_ptr. This way ownership is handled for you.
Jonathan, what compiler are you using? There's a great chance that shared_ptr already comes shipped with it as part of the compiler's TR1 implementation.