Re: const foo * and const foo &
Ulrich Eckhardt wrote:
Ralf Goertz wrote:
struct foo;
struct Bar {
void bar(const foo &) {
}
};
vector<vector<const foo*> >v;
This may seem trivial to manage in small programs, but in larger programs
it is easy to lose track of who owns the objects pointed to here. Using
smart pointers helps. Not using dynamically allocated objects helps, too,
but might create different problems.
I know what you mean. But in my program those foo object are created at
the beginning, put in a map and then never touched again. So I am pretty sure
that that is not a problem. And my original design was somewhat different, I
changed it in the course of debugging.
int main() {
foo f;
Bar b;
v.push_back(vector<const foo * >(1,&f));
b.bar(*v.back().back()); // (*)
return 0;
}
This compiles. But when I omit the dereferencing in the marked line the
compiler complains (as it should):
error: no matching function for call to 'Bar::bar(const foo*&)'
The problem is: in the big program I do exactly the same. But here the
program compiles *whether* *or* *not* I dereference. How can that be?
There must be a conversion between "foo const*" and "foo". Two things to
watch out for:
1. Make sure you have copying and assignment under control. If in doubt,
disable both by declaring the according functions private and not
implementing them.
Good point. I added
private:
explicit foo();
explicit foo(const foo &);
foo & operator=(const foo&);
without implementing them. That gave problems with the map but after
commenting out those lines the program still compiled.
2. Watch out for implicitly callable constructors. If you have a ctor for
an A that takes a B as parameter, it can be invoked implicitly when
calling a function that takes an A with a B as parameter. To prevent that,
make sure that the constructor is declared as "explicit". Note that this
also applies to constructors that have effectively one argument due to
default values for the others.
That's it. After declaring every contructor explicit the compiler did
complain. So here is the small programm again which does not complain.
Thank you very much. Seems so easy when it is explained.
#include <vector>
struct foo { };
struct Bar {
void bar(const foo &) { }
void bar(bool) {} //needs to be explicit
};
int main() {
foo f;
Bar b;
std::vector<std::vector<const foo*> >v;
v.push_back(std::vector<const foo * >(1,&f));
b.bar(v.back().back()); // implicit conversion
return 0;
}