Keeping a reference instead of a pointer? - c++

I have a class which basically is a text manager. It can draw text and whatnot. I basically want the color and text std::string to only be a constant reference. Would it then be alright to do
class TextManager {
const std::string &text;
void draw(const std::string &text) const;
public:
TextManager(const std::string &text)
{
this->text = text;
}
void someMethod()
{
draw(text);
}
};
I want when the class that owns an instance of TextManager's text changes, the change is reflected in the TextManager.
would I be better off using a pointer?
thanks

If you never need to re-seat the reference (i.e. refer to a different object), then it's fine. But in my experience, you'll inevitably find out later down the line that you need to be more flexible, in which case a reference is a pain. It may be better to go with a pointer from the start.
But note that you can only initialise a member variable of reference type in the constructor initialiser list. (Also, you probably want to declare that constructor as explicit).

This code doesn't compile. this->text = text doesn't do what you think it does - it's not like Java where assigning a reference is like changing the pointer. reference = value will actually invoke the copy operator, so it will copy the value of the rhs to the lhs, either as member-by-member copy or using the operator= if it was overridden. Since your text is const, you can't do that.
So in this case, you have to use a pointer - references cannot be modified once initialized.
EDIT: Just to explain ways in which you could use a reference:
const std::string &text = yourString;
or:
TextManager(const std::string &textRef)
: text(textRef)
{
}
That way, you have a permanent reference to whatever string you have.

Once you have sorted out the initialisation (which other comments can help you with), using a reference will let you do what you want. That is, changes to the referenced std::string will affect your class because they are the same std::string.
You can get similar behaviour using std::string const* instead of std::string const&. As Oli brought out, using a pointer is more flexible. Since a pointer can be null and can be updated using a pointer will allow you to define a default constructor and a (probably compiler generated) assignment operator. Which may not be important in this class but likely will be in some other class you will write (eg if you want to put objects of this class into a std::vector). So you probably are better off using a pointer internally. Though you may wish to still pass a reference to the constructor and take the address of it to initialise the member.

Related

C++ Destructor Called Multiple Times

I'm making a little wrapper class for sqlite. To get data to/from the database I have a class called SQLiteValue. When binding data for a query SQLiteValue instances get created on the stack and passed around a few functions. A skeleton outline of the class is below.
class SQLiteValue : public SQLiteObject
{
private:
// stores a pointer to the data contained (could be of varying types)
union
{
int* i;
double* d;
std::string* s;
std::wstring* ws;
BYTE* b;
} pdata;
int type;
public:
SQLiteValue(const char* val);
SQLiteValue(const wchar_t* val);
.. and so on for varying types
virtual ~SQLiteValue();
};
The object gets created by one of several overloaded constructors. The constructors instantiate a "member" of pdata based on their type. This is the important thing for this class. Now, the problem. I have the constructors overloaded so I get clean method calls and don't need to explicitly call SQLiteValue(xxx). As such I don't really want to use references for functions, so I define them like.
void BindValue(const char* name, SQLiteValue value)
query->BindValue(":username", "user2"); // the "clean" method call
Declaring them like this causes a new object to be instantiated every time (or something similar?) I call a function and so the destructor frees memory allocated for pdata. This is bad.
What I'd like to know is this. Is there a better way to achieve what I'm trying to do whilst retaining my clean method calls? At the moment I have private functions which operate by reference which solves the issue, but I don't really like this method. It would be easy for me to forget the reference and I'd end up tracking down this same issue again.
Thanks.
Change BindValue to take parameter by const reference.
void BindValue(const char* name, const SQLiteValue &value)
This is situation when rvalue reference can help. It doesn't reduce amount of constructors/destructors called, but allows to "steal" internal resources of temporary class instances in rvalue (&&) copy constructor or operator=. See details here: http://blogs.msdn.com/b/vcblog/archive/2009/02/03/rvalue-references-c-0x-features-in-vc10-part-2.aspx
rvalue reference copy constructor just moves another instance internal resources to "this" instance, and resets another instance resources to 0. So, instead of allocation, copying and releasing, it just copies a pointer or handle. "user2" in your code is such temporary instance - rvalue reference.
This can be applied to any C++ compiler implementing C++0x standard.

Returning strings by reference cpp

Forgive me if this has been asked before, I am sure it has but I couldn't find an answer I was happy with.
I am coming to cpp from a heavy Java background and would like to understand when to return a reference/pointer to an object rather than a copy.
for the following class definition:
class SpaceShip {
string name;
WeaponSystem weaponSystem; //represents some object, this is just an example, I dont have this type of object at all in my program
int hull;
string GetName() const {
return name;
}
WeaponSystem GetWeaponSystem() const {
return weaponSystem;
}
int GetHull() const {
return hull;
}
};
I know that returning a copy of things is expensive, I would think this means I want to avoid returning something like a string or weaponSystem by value, but an int by value is ok.
Is this right? I also know that I need to be aware of where things live in memory, does returning a reference to something in this class mean danger down the line if this object is destroyed and something still owns a reference to it's name?
On your last point, you definitely need to be a lot more careful about resource management in C++ than in Java. In particular, you need to decide when an object is no longer needed. Returning by reference has an effect of aliasing to the returned object. It is not noticeable when the object you are sharing is immutable, but unlike Java's Strings, C++ string are mutable. Therefore if you return name by value and then rename your SpaceShip, the caller would see the old name even after the renaming. If you return by reference, however, the caller will see a change as soon as ShaceShip is renamed.
When you deal with copying complex objects, you can decide how much is copied by providing a custom implementation of a copy constructor. If you decide to provide a copy constructor, don't forget the rule of three, and override the other two.
It "works" but you should have
const string& GetName() const {
It may also be beneficial to have the following also
const WeaponSystem& GetWeaponSystem() const {
Also, class is private by default, as such, your accessor functions are private.
the thing you have to know is every getter of your class must be prototype like that :
const <type> &className::getXXX() const
{
...
}
and every setter you make like that :
void className::setXXX(const <type> &)
{
...
}
Use reference when it's possible.
Sometimes, with complex object you can use pointer. That's depend on your code structure.

C++ private pointer "leaking"?

I'm going to create a class to hold a long list of parameters that will be passed to a function. Let's use this shorter example:
class ParamList{
public:
ParamList(string& a_string);
string& getString(); //returns my_string
private:
string& my_string;
}
My question is this: my_string is private, yet I'm returning the reference to it. Isn't that called something like private pointer leaking in C++? Is this not good programming practice? I want callers of getString to be able to get the reference and also modify it.
Please let me know.
Thanks,
jbu
edit1: callers will use getString() and modify the string that was returned.
Returing a private reference is perfectly okay so long as:
A. That is a const reference, and you have documented when that reference can be invalidated or
B. That reference is intended to be modified (i.e. std::vector<T>::operator[])
While there are useful cases for returning a non-const reference you should usually avoid it. This is covered in Scott Meyers' Effective C++ (3rd Edition, Item 28): Avoid returning "handles" to object internals, if you'd like to take a look.
First off, you need to decide if the ParamList is going to own the string or just "know about it". The way you've written it, with string& my_string, means that it just has a handle onto someone else's string. In that case, it's not (much of) a problem for some to modify the string since ParamList doesn't own it in the first place!
If you want ParamList to have a full master copy of the parameters (depends on the problem you're trying to solve), do something like this:
class ParamList{
public:
ParamList(const string& a_string); // do a strcpy in here.
const string& getString(); //returns my_string
void setString(const string& new_string); //do a strcpy here too.
private:
string my_string;
}
Note that it's probably better to use set and get functions anyway rather than returning a non-const reference, just so ParamList can have a little more control over how its members are modified.

C++: how to deal with const object that needs to be modified?

I have a place in the code that used to say
const myType & myVar = someMethod();
The problem is that:
someMethod() returns const myType
I need to be able to change myVar later on, by assigning a default value if the object is in an invalid state. So I need to make myVar to be non-const.
I assume I need to make myVar be non-reference as well, right? E.g. myType myVar?
What is the C++ "correct" way of doing this const-to-nonconst? Static cast? Lexical cast? Something else?
I may have access to boost's lexical cast, so I don't mind that option, but I'd prefer the non-boost solution as well if it ends up i'm not allowed to use boost.
Thanks!
You probably don't need any cast. If you can copy a T, then you can also copy a T const, pathological cases excluded. The copy of the T const need not be a T const itself.
myType myVar = someMethod(); // Creates a non-const copy that you may change.
I wouldn't use the const_cast solutions, and copying the object might not work. Instead, why not conditionally assign to another const reference? If myVar is valid, assign that. If not, assign the default. Then the code below can use this new const reference. One way to do this is to use the conditional expression:
const myType& myOtherVar = (myVar.isValid() ? myVar : defaultVar);
Another way is to write a function that takes a const reference (myVar) and returns either myVar or defaultVar, depending on the validity of myVar, and assign the return value from that to myOtherVar.
A third way is to use a const pointer, pointing it at either the address of myVar or the address of the default object.
const_cast<type without const>()
But, does someMethod() really return const myType? If so, you are making a reference to a temporary -- it will be destroyed and your reference will be bad. Change myVar to non-ref (so it copies) -- no need to declare it const in that case. Or, if someMethod() returns a reference, use the const_cast if you must (but you are changing something that someMethod thought wouldn't change).
There's no "C++" way (not only to this, but to anything).
The bad way is to use a const_cast, but the behavior will then be undefined (read: don't do that).
What you should do is copy the object and then modify the copy. It's the only proper way to deal with immutable objects.
Try the following
myType& mutableMyVar = const_cast<myType&>(myVar);
In general removing const is a bad idea though. The caller method returned you a reference to a variable it believes will be treated as const. If you violate this assumption by removing the const and modifying the variable you could put either object into a valid state.
It may be legal in your particular case but in general this is something to be avoided
You can creat an object from the const object using copy constructor or something assignment operator and then modify it.
But I think you would be better off seeing why the function was returning const type in the first place. There would have been a reason why it was declared const. If you are very sure that that is what you wanted, you can always const_cast away the constness like this:
T obj1 = const_cast<T&> (obj);
What is the C++ "correct" way of doing this const-to-nonconst? Static cast? Lexical cast? Something else?
There is no C++ way. For one reason or another, the author of that class decided that you should not be able to modify the instance through this method.
If you were the author, you could make it return a non-const reference. But those are still suspicious, unless the class really has no business hiding it from you (e.g like vector doesn't hide what it holds for you, and just hides how it holds stuff for you).
A better way (depending on what this is all about) might also be not to expose members for external manipulation, but rather provide a method that does this manipulation for you. For example:
class BadPosition
{
int x, y;
public:
int& get_x() { return x; }
int& get_y() { return x; }
//...
};
BadPosition p;
p.get_x() += 1;
p.get_y() += -1;
class BetterPosition
{
int x, y;
public:
void move(int x_inc, int y_inc) { x += x_inc; y += y_inc; }
//...
};
BetterPosition p;
p.move(1, -1);
If you need this to put the class in a valid state later, then perhaps consider making its constructor do that. If you cannot do that, at least provide an Init() method, so as not to make such a complicated class rely entirely on being externally manipulated into something usable.
There may be of course other ways not requiring a cast, e.g you could create a copy, modify that, and then use the modified copy to replace the whole instance with another one (assuming this is enough to construct it):
X x;
...
Y y = x.get();
y.modify();
x = X(y);
Edit: So the class returns by value? In this case there should be no way to modify the instance in the class, since all you get is a copy in the first place. You can reference that with a const reference, but even if you cast away constness from that reference, you are still referencing a temporary.
My reply above assumed it returned a const reference, since that would seem a more sensible thing to do (I haven't seen people often return by const value, although probably there are those who strongly recommend it).

C++ reference type recommended usage

I am programming in C++ more then 5 years, and have never met any place where reference of the variable is recommended to use except as a function argument (if you don't want to copy what you pass as your function argument). So could someone point cases where C++ variable reference is recommended (I mean it gives any advantage) to use.
As a return value of an opaque collection accessor/mutator
The operator[] of std::map returns a reference.
To shorten the text needed to reference a variable
If you miss old-school with Foo do ... statement (that's Pascal syntax), you can write
MyString &name = a->very->long_->accessor->to->member;
if (name.upcase() == "JOHN") {
name += " Smith";
}
another example of this can be found in Mike Dunlavey's answer
To state that something is just a reference
References are also useful in wrapper objects and functors--i.e. in intermediate objects that logically contact no members but only references to them.
Example:
class User_Filter{
std::list<User> const& stop_list;
public: Functor (std::list<User> const& lst)
: stop_list(lst) { }
public: bool operator()(User const& u) const
{ return stop_list.exists(u); }
};
find_if(x.begin(),x.end(),User_Filter(user_list));
The idea here that it's a compile error if you don't initialize a reference in constructor of such an object. The more checks in compile time--the better programs are.
Here's a case where it's handy:
MyClass myArray[N];
for (int i = 0; i < N; i++){
MyClass& a = myArray[i];
// in code here, use a instead of myArray[i], i.e.
a.Member = Value;
}
Use references wherever you want, pointers when you are forced to.
References and pointers share part of their semantics: they are an alias to an element that is not present. The main difference is with memory managements: references express clearly that you are not responsible for the resource. On the other hand, with pointers it is never really clear (unless you mean smart pointers): are you assumed to delete the pointer or will it be deleted externally?
You must use pointers when you must manage memory, want to allow for optional semantics or need to change the element referred to at a later time.
In the rest of cases, where you can use a reference or a pointer, references are clearer and should be preferred.
Now, as you point out, they are really not needed: you can always use pointers for all the reference uses (even parameter passing), but the fact that you can use a single tool for everything does not mean there are no better suited tools for the job.
I tend to use reference members instead of pointers for externally controlled non-optional construction parameters.
EDIT (added example):
Let's say that you have a database and a DAO class having the database as a dependency:
struct Database {};
struct PersonDao {
const Database &m_d;
PersonDao(const Database &d): m_d(d) {}
};
Furthermore, the scope of the database is controlled externally from the DAO:
int main() {
Database d;
PersonDao pd(d);
}
In this case it makes sense to use a reference type, since you don't ever want DAO::m_d to be null, and its lifetime is controlled externally (from the main function in this case).
I use references in function arguments not just to avoid copies but also instead of pointers to avoid having to deal with NULL pointers where appropriate. Pointers model a "maybe there's a value, but maybe not (NULL)", references are a clear statement that a value is required.
... and to make it absolutely clear (-> comments). I tend to avoid pointers to model "maybe there are several values" - a vector is a better option here. Pointers to several values often end up in C-style programming because you usually have to pass the # of elements as well separately.
Use a const reference to give a name to a value, e.g.:
const Vec3 &ba=b-a;
This names the value, but doesn't necessarily create a variable for it. In theory, this gives the compiler more leeway and may allow it to avoid some copy constructor calls.
(Related non-duplicated Stack Overflow question at Const reference to temporary. The Herb Sutter link there has more information about this.)
The argument to the copy-constructor MUST be passed as a reference, since otherwise the copy constructor would need to call it self in an endless recursion (stack overflow).
I tend to agree, but perhaps const return values.
Well you kind of have two choices for aliasing other values(ignoring shared_ptrs and the like): pointers and references.
References must be initialized at construction to refer to something else. So semantically a reference can never be NULL. In reality, though, the underlying data can go away, giving you problems often more difficult to debug than if a pointer went away. So I'm not sure there's a real advantage here unless you were disciplined and consistent with how they were used vis-a-vis referring to items that were dynamically allocated. If you did this with pointers too, you'd avoid the same problems.
Perhaps more importantly, references can be used without thinking about all the issues that arise with pointers. This is probably the main advantage. Semantically a reference is the thing. If you guarantee as the caller/callee that the underlying memory doesn't go away, you don't have to confuse the user with any of the questions that come along with pointers (Do I need to free this? Could this be NULL? etc) and can safely use a reference for convenience.
An example of this might be a function that looks up the corresponding string for an enum,
const std::string& ConvertToString( someEnum val)
{
static std::vector< std::string > lookupTable;
if (lookupTable.empty())
{
// fill in lookup table
}
// ignoring the cast that would need to happen
return lookupTable[val]
}
Here the contract between the caller and the callee guarantees that the return type will always be there. You can safely return a reference, and avoid some of the questions that pointers invite.
References make code prettier. So use them whenever it takes a reference to beautify your code.
i would like to enlist some cases:
1) while writing singleton classes
class singleton
{
singleton();
explicit singleton(const singleton&);
singleton& operator=(const singleton&);
public:
static singleton& instance()
{
static singleton inst;
return inst;
}
};// this is called the 'Meyers' singleton pattern. refer to More Effective C++ by Scott Meyers
it has all the benefits, but avoids using the new operator
**2)**here is no such thing as a null reference. A reference must always refer to some object. As a result, if you have a variable whose purpose is to refer to another object, but it is possible that there might not be an object to refer to, you should make the variable a pointer, because then you can set it to null. On the other hand, if the variable must always refer to an object, i.e., if your design does not allow for the possibility that the variable is null, you should probably make the variable a reference
**3)**Because a reference must refer to an object, C++ requires that references be initialized:
string& rs; // error! References must
// be initialized
string s("xyzzy");
string& rs = s; // okay, rs refers to s
Pointers are subject to no such restriction
The fact that there is no such thing as a null reference implies that it can be more efficient to use references than to use pointers. That's because there's no need to test the validity of a reference before using it
**4)**Another important difference between pointers and references is that pointers may be reassigned to refer to different objects. A reference, however, always refers to the object with which it is initialized: ยค Item M1, P10
string s1("Nancy");
string s2("Clancy");
string& rs = s1; // rs refers to s1
string *ps = &s1; // ps points to s1
rs = s2; // rs still refers to s1,
// but s1's value is now
// "Clancy"
ps = &s2; // ps now points to s2;
// s1 is unchanged
Stream operators are an obvious example
std::ostream & operator<< (std::ostream &, MyClass const &...) {
....
}
mystream << myClassVariable;
You obviously don't want a pointer as checking for NULL makes using an operator very tedious i.s.o. convenient
I've used a reference to an ostream instead of a pointer. I supppose that I prefer references to pointers when the class has a lot of operators.