Consider the following, simplified facade pattern:
class Foo {
public:
int times;
int eval(const int val) { return val*times; }
};
class Bar {
Foo foo;
public:
Bar(const Foo& f) : foo(f) {}
double eval(const double val) { return val * foo.times; }
};
Obviously, an instance of Bar is only required to evaluate a special (i.e. double-valued) interpretation of Foo's eval() method. A Bar won't have any other members except the foo it forwards to.
For safety reasons I have not used a const reference or a pointer inside Bar (I just don't know yet if at some point a Bar instance might escape from a stack frame, so resource management is important).
My question here is two fold:
Can the C++ compiler possibly detect that Bar is merely a facade and
"inline" the member access?
Is there a (safe) way to prevent copying
of the passed object?
On some platforms (gcc/clang) you can force inlining with the attribute always_inline or emit warnings should a function not be inlined.
No, if you don't want to copy, you need to guarantee the life-time of the object elsewhere. If you consider this to be unsafe, don't do it. What you can do is move an object. This avoids copies and life-time issues, but might not be possible with your compiler.
For example:
struct Bar {
// Only accept rvalues of Foo
explicit Bar(Foo&& f) : f(std::move(f)) {}
Foo f;
};
1- Yes, the compiler will most probably inline the function [It depends on compiler).
2- Always stick to RAII. In C++3, Foo object foo shall be either member variable (as you did), or managed pointer (copied at copy constructor and assignment operator and deleted at destructor). In C++11 you can use right value reference.
NOTE: This example is not a facade!
Related
I have a class Foo having the rights to read an instance of class Bar, but doesn't have the rights to modify it. In the same time, the instance of Bar could be modified by other elements.
For the moment, I implement it by this way:
class Foo
{
private:
const Bar& bar; // Foo can't modify it
public:
Foo(const Bar& bar_) : bar(bar_) {}
void doSomthing() { this->bar.printData(); }
};
And it could be used like this:
Bar bar;
Foo foo(bar);
bar.update(); // This modify the instance of Bar
foo.doSomthing(); // This use the reference to (modified) bar
My question is: With this implementation, can I be sure than the compiler doesn't use a non updated copy of bar even if the reference is declared as const ?
If no, how can I do that ?
Note: I don't use C++11 for compatibility reason
Yes, you can be sure. References are internally implemented in the compiler as pointers, and both bar.update(); and Foo::bar are acting on the same memory location.
That's, of course, as long as there are no data race concerns, at which point the usual problems of synchronization arise.
The best pre c++11 standard text I could find quickly was this draft from 2005, wich should be close enough to C++03.
It says in 3.10:13 [basic.lval]
The referent of a const-qualified expression shall not be modified (through that expression), except that if it is of class type and has a mutable component, that component can be modified.
The emphasis is mine and highlights that it is to be expected that the referent can be modified though other expressions (if they themselves allow it).
This question asks for a clean way of implementing a static factory method in C++, and this answer describes a clear way to do so. Return Value Optimization would save us from making an unnecesary copy of Object, thus making this way of creating an Object as efficient as directly invoking a constructor. The overhead of copying i to id inside a private constructor is negligible because it's a small int.
However, the question and answer don't cover a more complex case when Object contains an instance variable that is an instance of class Foo (that requires complex initialization logic) rather than a small primitive type. Suppose I want to construct Foo using the arguments passed to Object. A solution using a constructor would look something like:
class Object {
Foo foo;
public:
Object(const FooArg& fooArg) {
// Create foo using fooArg here
foo = ...
}
}
An alternative with a static factory method analogous to the quoted answer would be, as it appears to me:
class Object {
Foo foo;
explicit Object(const Foo& foo_):
foo(foo_)
{
}
public:
static Object FromFooArg(const FooArg& fooArg) {
// Create foo using fooArg here
Foo foo = ...
return Object(foo);
}
}
Here, the overhead of copying foo_ to foo is no longer necessarily negligible, since Foo can be an arbitrarily complex class. Moreover, as far as I understand (C++ newbie here so I may be wrong), this code implicitly requires for a copy constructor to be defined for Foo.
What would be a similarly clean but also efficient way of implementing this pattern in this case?
To anticipate possible questions about why this is relevant, I consider having constructors with logic more complicated than just copying the arguments to be an anti-pattern. I expect the constructor to:
be guaranteed to work and not throw exceptions,
and not do heavy calculations under the hood.
Thus, I prefer to put complex initialization logic into static methods. Moreover, this approach provides additional benefits such as overloading by static factory method name even when the input argument types are the same, and the possibility of clearly stating what is being done inside in the name of the method.
Thanks to move constructor, you might do:
class Object {
Foo foo;
explicit Object(Foo&& foo_) : foo(std::move(foo_)) {}
public:
static Object FromFooArg(const FooArg& fooArg) {
// Create foo using fooArg here
Foo foo = ...
return Object(std::move(foo));
}
};
If Foo is not movable, wrapping it in smart pointer is a possibility:
class Object {
std::unique_ptr<Foo> foo;
explicit Object(std::unique_ptr<Foo>&& foo_) : foo(std::move(foo_)) {}
public:
static Object FromFooArg(const FooArg& fooArg) {
// Create foo using fooArg here
std::unique_ptr<Foo> foo = ...
return Object(std::move(foo));
}
};
What is wrong with initializing the instance in the constructor directly from the arguments needed to do so?
class Object
{
Foo foo; // or const Foo foo, disallowing assignment
public:
explicit Object(FooCtorArgs const&fooArg,
const AdditionalData*data = nullptr)
: foo(fooArg) // construct instance foo directly from args
{
foo.post_construction(data); // optional; doesn't work with const foo
}
static Object FromFooArg(FooCtorArgs const&fooArg,
const AdditionalData*data = nullptr)
{
return Object{fooArg,data}; // copy avoided by return value optimization
}
};
AFAICT, there is no need to copy/move anything, even if you need to adjust foo post construction.
I am in the process of boning up on my C++ (as in, attempting to get into more modern-style coding) and am looking at the delete specifier. It is my understanding that it is used to make sure that certain functionality cannot be defined or called. If I understand it correctly, this is primarily within the domain of assignment and copy. I am not quite sure what the difference is between using the delete specifier and just making those functions private.
For instance, what is the difference between:
class Foo {
private:
Foo& operator(const Foo&);
Foo(const Foo&);
};
And
class Bar {
public:
Bar& operator(const Bar&) = delete;
Bar(const Bar&) = delete;
};
In other words: what does using the delete specifier gain? Is it just to make things look nicer?
One obvious difference is that if you make the function private, then it is still accessible from within the class and any friends.
An explicitly deleted function is not usable anywhere, so you know simply from that one line that it's never used, without having to inspect the implementation.
You can make the function both private and deleted: then its participation in overload resolution is more consistent.
It's simpler.
This way, your intent is clearly stated and your compiler can outright say "calling this function is prohibited".
Otherwise you're relying on:
access control (for attempted calls from outside of the class), or
the linker giving you an "undefined reference" near the end of your build process. That's kind of okay for small programs where you can quickly find out what's going on, but for deep class hierarchies where some many-times-over encapsulated object cannot be copied but has not been deleted, good luck debugging that.
Short answer is: uses of a deleted function make the program ill-formed and you are notified at compile-time, uses of a function that is not defined end in an odd error that comes out of the linker.
As an example, there is a relevant part of the standard that states:
A program that refers to a deleted function implicitly or explicitly, other than to declare it, is ill-formed.
Therefore, the following compiles just fine:
struct S {
void f();
};
template<typename T, void (T::*M)() = &T::f>
void g() {}
int main() {
g<S>();
}
While the code below does not:
struct S {
void f() = delete;
};
template<typename T, void (T::*M)() = &T::f>
void g() {}
int main() {
g<S>();
}
That's because in the second case the code is ill-formed and you have a compile-time error in any case, no matter if you are going to use or not M. In the second case, you get an error out of the linker only if you try to use it:
template<typename T, void (T::*M)() = &T::f>
void g() {
T t;
(t.*M)();
}
Of course, compile-time errors are much better to prevent issues. The example uses public functions, but making them private doesn't prevent from using them within the class in similar ways. That's just a toy example to show a possible difference.
I have a class with a header like this:
public:
const dtMeshTile* getTile(int i) const;
private:
dtMeshTile* getTile(int i);
When I try to use it like this:
const dtMeshTile* const tile = navmesh->getTile(i);
I'm getting a "'dtMeshTile* getTile(int)' is private within this context" How can I specify the public function?
Consider:
#include <cstdlib>
class Bar {};
class Foo
{
public:
Foo (Bar& bar)
:
mBar (bar)
{
}
const Bar& get() const
{
return mBar;
}
private:
Bar& get()
{
return mBar;
}
Bar& mBar;
};
int main()
{
Bar bar;
Foo foo (bar);
Bar& ref = foo.get();
}
At the point of the call: const Bar& ref = foo.get(); you might expect the const version of get() to be called, because you are assigning a const reference.
But this is not the case. Return types are not a part of a function's (or method's) signature, so when the compiler is looking for which function to call in a list of possible overloads, the return type is not considered. (In fact, the Standard rejects function overloads which differ only by return type.)
So, how does the compiler decide which function to call? By looking at the information is does have available to it. The tweo overloads are identical in terms of parameters (both are void), so the only thing it has to go on is the static type of the object used to make the call: foo. That static type in this case is Foo -- decidedly non-const.
Therefore it tried to call the only function it can: the non-const version of get(). Which of course won't compile because that is private.
In order to fox this, the static type can be changed to be a const Foo (or something similar), like this:
Foo foo (bar);
Bar& ref = foo.get();
Or maybe...
Foo foo (bar);
const Bar& ref = static_cast <const Foo&> (foo).get();
But in practice, I would rather advise that the names of these functions be unambigious, rather that relying on such "tricks" to contort the compiler in to doing what you want.
make sure navmesh is const in the context of your call. But I would not recommend const_cast it, you might read this http://www.parashift.com/c++-faq/overview-const.html .
You're hit by a pretty common design flow -- an overload set with mixed semantics.
But I guess you can't change the class, only work around it.
Your problem comes from overload resolution rules. The function is selected based on arguments. Only. private/public stuff is ignored at this stage. The selection happens based on the type before -> if if it's const T*, the first function is selected, for T* the second.
Assess check is applied then, so for the latter case you get the error report. To force the desired function you must use a cast, or better create a free wrapper function
const dtMeshTile* getXXXTile(const XXX* p, int i) {return p->getTitle(i);}
(or a ref-taking variant).
In my codebase the second function would have a different name, as obtaining a mutable string is way different in semantics.
My head hurts: I've read so many blogs about C++11x's move semantics that my brain's gone mushy, so please can someone give me a short-but-sweet guide on how to make the following code work efficiently? Given a class Foo, I want to be able to write functions that return Foo objects in different states (sometimes called source functions), and to do this as efficiently as possible.
class Foo {
// Some methods and members
};
Foo getFirstFoo() {
Foo foo;
// Do some things to foo
return foo;
}
Foo getSecondFoo() {
Foo foo;
// Do some different things to foo
return foo;
}
int main() {
Foo f = getFoo();
// use f ...
f = getSecondFoo();
// use f ...
return 0;
}
I don't want to modify Foo much, and the idea is to allow all sorts of Foo objects to be created through a variety of non-member source functions, so adding ever more constructors would be missing the point.
In C++03 my options would be to wrap the returned object in an auto_ptr (a big downside being that the recipient code needs to know to handle a smart pointer), or to cross my fingers and hope that some sort of optimization might take place (likely for the first line in main, less so for the second). C++11x seems to provide something better through move semantics, but how would I take advantage of these? So I need to change the way objects are returns in the source functions, or add some move constructor to Foo, or both?
This is already optimal1, provided that move constructors are generated2:
class Foo {
public:
Foo(Foo&&) = default;
Foo& operator=(Foo&&) = default;
};
Returned values are rvalue references by default.
1 Well.... provided that your class Foo benefits from move construction at all. Remember, move is an optimization of copy. Some copies cannot be improved! E.g, unsuited:
struct Foo { int data; };
struct Foo2 { int data[5<<10]; };
well suited:
struct Foo3 { std::vector<std::string> data; };
See Move semantics - what it's all about? for a more general background on things like this.
2 Not all compilers do support that yet (even if they do implement rvalue references), so you might have to write the
move constructor
move assignment