This question already has answers here:
Reference as class member initialization
(4 answers)
Closed 9 years ago.
I am sorry if this meight be a really simple question but i am new to c++ and working on a simple vocable trainer for understanding c++. (come from java..)
I'd like to pass a const FileManager as reference to my Logic. But i don't get it work. I don't want to have a copy or such.
So i tried it like this: (the main)
FileManager& file = FileManager();
Logic logic = Logic(file);
Inside of the Logic i'd like to store the reference:
class Logic
{
public:
Logic(const FileManager& manager);
~Logic();
private:
const FileManager& m_fileManager;
};
Logic::Logic(const FileManager& manager) :
{
m_fileManager = manager;
}
Thanks
Once the body of a constructor is entered, all member variables have already been initialized. Thereafter, you can only assign to them. This can't work with references - as we know, they need to be initialized when their lifetime begins.
You need to use member initializer list:
Logic::Logic(const FileManager& manager)
: m_fileManager(manager) // m_fileManager is initialized here
{
}
Consider if you really want a reference member. For one, they make your class non-assignable. A smart pointer might be a better choice.
Your example has three flaws. The first, is that you try to initialize a none const reference with a temporary object:
FileManager& file = FileManager();
Most likely you just want to use a FileManager instance here:
FileManager file;
Second, references must be initialized. You achieve this by using the initializer list syntax:
Logic::Logic(const FileManager& manager)
: m_fileManager( manager )
{
}
In addition, the initializing, you use for Logic requires that Logic is assignable. Simply use:
Logic logic(file);
If you have reference members in a class, objects of that class are not assignable by default.
Related
This question already has answers here:
How to initialize the reference member variable of a class?
(2 answers)
Closed 2 years ago.
I'm trying to pass a class reference to a field, but I get the error "'mazeGenerator::maze' references must be initialized".
I tried initializing 'maze' above the class constructor.
Why is this happening?
class mazeGenerator {
public:
Maze& maze;
mazeGenerator(Maze& mazeObj) {
maze=mazeObj;
}
}
You must initialize data members of reference type with a member initializer list, like this:
mazeGenerator(Maze& mazeObj) : maze(mazeObj) {}
This is also the case with const data members.
Note that putting the declaration of the data member above the constructor doesn't actually make any difference; it could be declared below as well.
Also, your data members (whether they are of reference type or not), should be private to the class.
This question already has an answer here:
Using references to access class objects C++
(1 answer)
Closed 7 years ago.
I have this lines:
class ModulePeople : public Module {
public:
std::list<People> & list_people;
std::list<People>::iterator it;
}
When I try to compile I have this error:
Compiler Error C2758
'ModulePeople': a member of reference type must be initialized
This error appears in this line for example:
it = list_people.begin();
But I don't really know how to inicializate this kind of variable, because i can't do it to NULL. If somebody can help me it would be very grateful.
A reference is an alias for an existing object with storage space somewhere. This means that a reference must reference (no pun intended) an existing object, it's not like a pointer which can has value of nullptr.
This implies that if you use a reference as a member field of a class definition then you must initialize it through any available constructor of such object, eg:
class ModulePeople : public Module {
public:
std::list<People> & list_people;
std::list<People>::iterator it;
ModulePeople(decltype(list_people) list_people) : list_people(list_people) { }
}
If you really want to be able to let it point to nothing then could use a pointer instead, eg std::list<People>*.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I know how useful it is to declare variable as a reference or pointer in a function, but I just wonder why we declare it as a reference in the private section of a class.
example
class DoSomething
{
private : int& t_; // why not just 'int t;'
};
How about if we declare the variable without reference, and define the object of a class as a pointer or reference? Is this not good practice?
If you declare the variable as int, its value would be "divorced" from the variable from which it has been initialized. If you keep it a reference, the variable would be "tracking" the variable with which it has been initialized:
class demoRef {
int &r;
public:
demoRef(int& x) : r(x) {}
void show() {cout << r << endl;}
};
class demoCopy {
int r;
public:
demoCopy(int& x) : r(x) {}
void show() {cout << r << endl;}
};
int main() {
int x = 123;
demoRef dRef(x);
demoCopy dCopy(x);
dRef.show();
dCopy.show();
x = 456;
dRef.show();
dCopy.show();
return 0;
}
This code produces the output below:
123
123
456
123
Demo on ideone.
Note: this is only an illustration of what you can do with a reference to an int. It is not meant to imply that you should do something like this without being extra careful, because a hidden reference like this makes your code harder to read.
There are many reasons you might have a reference member. An example from the standard library is the back_insert_iterator, which keeps a reference (or a pointer) to a container in order to call that container's push_back function.
Note that with any class like this, which stores a reference or pointer to another object, you need to take the same care as you would with a raw reference or pointer. That is, you need to be wary of dangling references, and ensure that you don't use the reference past the lifetime of the referent.
When you store a reference to a variable in a class, the outcome of changing the variable is:
You can change the variable in a member function of DoSomething and have that change be visible outside the class.
You can change the variable outside DoSomething and have that change be visible inside DoSomething.
The key question is: Where is it useful?
I have often found it useful in a functor that is passed to some of the functions in the standard library.
#BenjaminLindley already gave you a very good example of that.
I have often found it useful in Factory Patterns when a concrete Product is created using the data stored in a concrete Factory but the data is too expensive to copy.
I have used it in classes that implement a functional interface. These classes hold references to other data when:
3.1. The class needs to access to the data but it is too expensive to copy the data.
3.2. It makes no sense to copy the data or copying is prohibited by design (such as std::ofstream).
3.3. The class needs to update the data and make it visible to the calling code.
This question already has answers here:
When do we need to have a default constructor?
(7 answers)
Closed 8 years ago.
I have the following classes:
class ArithmeticExpression
{
public:
ArithmeticExpression(std::string expr);
}
class Command
{
public:
Command(){};
//this is a virtual class
}
class CommandAssign : public Command
{
private:
ArithmeticExpression expr;
public:
CommandAssign();
CommandAssign(ArithmeticExpression);
}
Now when I try to write the constructor for the CommandAssign class as in:
CommandAssign::CommandAssign(ArithmeticExpression expr)
:Command()
{
this -> expr = ArithmeticExpression(expr.getExpr());
}
I get the error:
no matching function for call to ‘ArithmeticExpression::ArithmeticExpression()’
:Command()
Apparently I can fix that by adding an empty constructor in ArithmeticExpression class that does not do anything. What is it so special about this empty constructor that makes it work? I do not explicitly call anywhere. Do you always need to define an empty constructor in C++?
I wanted to emphasize that although from the title it seems that my question is similar to the one some users suggested as being a duplicate of, the answer I was looking for is NOT there. I was simply trying to understand what happens when a constructor is called and how to avoid defining a useless default constructor, which I knew already is not automatically defined by the compiler in the case where I define one with parameters.
A default constructor will only be automatically generated by the compiler if no other constructors are defined.
EDIT:
The default constructor is needed for object initialization.
All members are initialised before the constructor body begins. If one doesn't have an entry in the initialiser list, then it will be default-initialised; but this is only possible (for a class type) if it has a default constructor.
expr is not initialised in the initialiser list, and doesn't have a default constructor (since declaring any constructor prevents one from being implicitly generated), so it can't be initialised - hence the error.
You should initialise it in the list, rather than reassigning it in the constructor body:
CommandAssign::CommandAssign(ArithmeticExpression expr) :
expr(expr.getExpr())
{}
Note that there's no need to explicitly default-construct the Command sub-object. This also requires the constructor of ArithmeticExpression to be public: it's private in your example code.
This question already has answers here:
Meaning of 'const' last in a function declaration of a class?
(12 answers)
Closed 9 years ago.
I am learning C++ in Qt environment and I was going through one of the sample code online.
Can anyone please explain this syntax to me?
const TicTacToe * GetTicTacToe() const { return m_tictactoe.get(); }
Why is there a const before the opening bracket of a function? Is it a pointer or multiplication?
the full class is as follows, but the syntax of the instructions mentioned above is not clear to me
class QtTicTacToeWidget : public QWidget
{
Q_OBJECT
public:
explicit QtTicTacToeWidget(QWidget *parent = 0);
const TicTacToe * GetTicTacToe() const { return m_tictactoe.get(); }
void Restart();
The first const is to signify that the variable pointer TicTacToe can't be changed. The second constant after the function declaration says that anything that happens inside this function will not change any member variable inside the class. Because it effectively does not change memory data on the class, it can be used when you use any constant object of that class. For example:
const QtTicTacToeWidget myConstObject;
// Since myConstObject is a constant, I am not allowed to change anything inside
// the class or call any functions that may change its data. A constant function
// is a function that does not change its own data which means I can do this:
myConstObject.GetTicTacToe();
// But I can not do the next statement because the function is not constant
// and therefore may potentially change its own data:
myConstObject.Restart();
The const between before the opening bracket signifies that the function is a const member function. It essentially says that it guarantees to not modify the class and therefore can be called on an object declared as const.
Well that, and it also allows the function to modify mutable variables in a const class.