Consider the following code snippet.
template <T>
MyPtr<T> CreateObject()
{
// Do something here first...
// return our new object
return MyPtr<T>(new T());
}
class Foo
{
private:
Foo() { }
public:
static MyPtr<Foo> GetNewInstance()
{
// ERROR: Foo is private...
return CreateObject<Foo>();
}
};
class Bar
{
public:
Bar() { }
};
int main()
{
MyPtr<Bar> bar = CreateObject<Bar>();
return 0;
}
Without resorting to macro for CreateObject (I like the syntax of MyPtr<type> obj = CreateObject<type>(params)), is there a way to make the function CreateObject share the same context as the caller function, thus able to access private Foo c'tor? 'friend' is not what I'm looking for as it would mean anyone calling CreateObject would have access to private Foo c'tor, which is not what I want. Overloading the new operator wouldn't work either as it is imperative that a MyPtr is returned instead of just T* (by assigning T* to MyPtr assigns a type to the object that is required somewhere else).
I guess what I'm looking for is something in between a macro and a template function (syntax of a template function but gets expanded fully like a macro). It would be quite useful to have this feature in this particular case.
Well, you could do that with the passkey pattern:
template<class T, class PassKey>
MyPtr<T> CreateObject(PassKey const& key)
{
return new T(key);
}
class FooKey{
private:
FooKey(){} // private ctor
FooKey(const FooKey&); // undefined private copy ctor
friend class Foo;
};
class Foo{
public:
// public ctor
Foo(FooKey const&){}
static MyPtr<Foo> GetNewInstance()
{
return CreateObject<Foo>(FooKey());
}
};
Example at Ideone.
With C++0x, this can be done much easier than creating a new Key struct every time, since template parameters are now allowed to be friends:
template<class T>
struct PassKey{
private:
PassKey(){}
PassKey(const PassKey<T>&);
friend T;
};
This is basically the same as attempting to use make_shared with a private constructor.
The only way to allow this is with friend. You're pretty much stuck in this case I'm afraid.
I am not sure as to what you are trying to achieve. The simplification to post the problem here has taken away the actual need for the whole thing. So I will just assume that you know what you are doing, and that you really need this (and I suggest that you rethink whether you do need it, as I don't see a point...)
At any rate, you can solve the problem by passing a creator callback to the CreateObject template:
template <typename T, typename Creator>
MyPtr<T> CreateObject( Creator creator )
{
// Do something here first...
return MyPtr<T>(creator());
}
class Foo
{
private:
Foo() {}
static Foo* create() { return new Foo(); }
public:
static MyPtr<Foo> GetNewInstance() {
return CreateObject<Foo>( &Foo:create );
}
// ...
};
The actual issue though, is what does Do something here first actually does that forces you into this complex creation patterns. The fact that it has to be executed before the creation of the new object seems to indicate that there are hidden dependencies not shown in the code, and that usually end up in maintenance nightmares, where someone down the line reorders some code, or adds a new constructor and everything seems to fall apart. Revisit your design and consider whether those dependencies can be simplified or made explicit.
Since you are newing up the object in the very end it really doesn't relate to your CreateObject function. So Change the function prototype to:
template <typename T>
MyPtr<T> CreateObject(T* const p)
{
//...
return MyPtr<T>(p);
}
Usage:
static MyPtr<Foo> GetNewInstance()
{
return CreateObject(new Foo());
}
is there a way to make the function CreateObject share the same context as the caller function
Yes, pass the context you need as an argument (either as an argument to the template, or as an argument to the function).
In practice, move the new T call to a separate function (or struct template, as I chose to do here), like this:
// Dummy representation of your pointer type
template <typename T>
struct MyPtr
{
MyPtr( T *p ) { }
};
// Default constructor template; may be specialized to not use "new" or so.
template <typename T>
struct Constructor
{
static T *invoke() { return new T; }
};
// Needs to be a struct (or class) so 'C' can have a default value
template <typename T, typename C = Constructor<T> >
struct CreateObject
{
MyPtr<T> operator()() {
return MyPtr<T>( C::invoke() );
}
};
class Foo
{
private:
friend struct Constructor<Foo>;
Foo() { }
public:
static MyPtr<Foo> GetNewInstance()
{
return CreateObject<Foo>()();
}
};
If you want to handle different constructor signatures (read: if not all types T have the same constructor signature), you could also choose to not pass the Constructor as a template to the CreateObject struct, but instead use a function argument. That way, you could 'load' a Constructor like this:
// ...
static MyPtr<Foo> GetNewInstance()
{
Constructor<Foo> c( arg1, arg2, arg3 );
return CreateObject<Foo>( c );
}
Related
I am working on game engine as a project during the summer. Every scriptable component should have access to some methods in the scene which they are in. To make this possible i pass lambdas from the scene that calls the respective methods to the scriptable where they are implicitly converted to std::function types.
Scene.h:
class Scene
{
private:
unsigned int _currentId;
std::vector<System*> _systems;
//SCRIPTABLE NEEDS THE BELOW METHODS THESE EXCLUSIVELY:
bool exists(unsigned id);
void destroy(unsigned int);
void addComponent(Component*, unsigned int);
template<typename T> T& getComponent(unsigned int);
template<typename T> bool hasComponent(unsigned int);
template<typename T> void removeComponent(unsigned int);
protected:
unsigned int instantiate(std::vector<Component*>);
public:
Scene(ChangeSceneCallback);
~Scene();
void initiate();
void update(long dt);
};
template<typename T>
inline T & Scene::getComponent(unsigned int id)
{
for (System* system : _systems) {
if (system->corresponds(T)) {
return static_cast<T*>(system->getComponent(entityId));
}
}
}
template<typename T>
inline bool Scene::hasComponent(unsigned int id)
{
for (System* system : _systems) {
if (system->corresponds(T)) {
return system->contains(id);
}
}
}
template<typename T>
inline void Scene::removeComponent(unsigned int id)
{
for (System* system : _systems) {
if (system->corresponds(T)) {
return system->destroy(id);
}
}
}
The callback method works for the non-template functions i need access to, but not the templated ones, so it's out of the question.
Scriptable:
typedef std::function<void(int)> ChangeSceneCallback;
typedef std::function<int(std::vector<Component*>)> InstantiateCallback;
typedef std::function<void(int)> DestroyCallback;
typedef std::function<bool(int)> ExistCallback;
typedef std::function<void(Component*, unsigned int)> AddComponentCallback;
class Scriptable: public Component
{
protected:
ChangeSceneCallback changeScene;
InstantiateCallback instantiate;
DestroyCallback destroy;
ExistCallback exists;
public:
~Scriptable();
Scriptable();
void assignCallbacks(ChangeSceneCallback, InstantiateCallback etc ...);
virtual void init() = 0;
virtual void update() = 0;
};
Scriptable can't have access to public methods in scene because this would give the user / developer access to them (Scriptable is a base class for the behaviour of the game). That is why i need to come up with something that gives scriptable limited access to scene.
Any thoughts?
You cannot have a type erased "template callback". You have to choose between the template or the type erasure. Let me explain.
This is what a "template callback" look like. This is in fact a generic lambda:
auto print_callback = [](auto var) {
std::cout << var << std::endl;
}
print_callback(4) ; // prints "4"
print_callback(4.5); // prints "4.5"
print_callback("hello"); // prints "hello"
It seems good but notice that you can't do that with std::function, since you have to predefine the signature.
std::function<void(int)> func_print_callback = print_callback;
func_print_callback(5); // Yay! Prints "5"
func_print_callback("hello"); // error
The thing is, you might think the limitation is only because std::function need a specific signature to work with, but the limitation is much deeper than that.
The thing is, the is no template function. They don't exists. Function template on the other hand, do exist. Why I emphasize so much on the order of my words is because the name of this thing says it all: it is not a function, it a template that is used to make functions.
Here's a simple example:
template<typename T>
void foo(T t) {
std::cout << t << std::endl;
}
This function is not compiled. Because it's not a function. No function foo will exist until the hole T has been filled.
How do you fill the hole named T supposed to be a type?
By filling it with a type of course!
foo(5.4); // the hole T is `double`
When the compiler sees this, it knows you need a function named foo that takes a double as parameter. There is no function named foo that takes a double. But we gave the compiler a tool to create one: the template!
So the compiler will generate this function:
void foo_double(double t) {
std::cout << t std::endl;
}
The word here is this: generate. The compiler need to create the function in order to exist. The compiler generate code for you.
When the function is generated and compiled, T do not exist anymore. A template parameter is a compile-time entity, and only the compiler knows about them.
Now, I'll explain to you why there is no such thing as a template callback.
Type erased container such as std::function are implemented with pointer to function. I'll use type aliases to ease the syntax a bit. It works like this:
// A function
void foo(int) {}
// The type of the pointer to function
using func_ptr = void(*)(int);
// A pointer to foo
func_ptr ptr = &foo;
The pointer to the function foo has a value that points to the location of foo in the memory.
Now imagine we have a way to have template function pointer. We would have to point to a function that does not exist yet. It has no memory location, so it cannot make sense. And through the pointer, when invoked as a function, you'd have to generate the function code.
Since a pointer to function can point to any function, even functions that aren't known to the compiler yet, you'd have to somehow generate the function code and compile it. But the value of the pointer, to which function our pointer points to, is defined at runtime! So you'd have to compile code at runtime, for code that you don't know yet, from a value that does not exist, when the compiler don't exist anymore. As you can see, pointer to template function, template std::function or virtual template function cannot exist.
Now that you have understood the problem, let me propose a solution: drop the callback usage. You should call those functions directly.
You seem to use callback only to be able to call private member functions. This is the wrong way to do it, even if it works. What you need is friend, the feature of C++ that allows you to access private members.
class Scene {
friend Component;
// ...
};
class Component {
protected:
// Let `scene` be a reference to your scene
void addComponent(Component* c, unsigned int id) {
scene.addComponent(c, id);
}
template<typename T>
T& getComponent(unsigned int id) {
return scene.getComponent<T>(id);
}
template<typename T>
bool hasComponent(unsigned int id) {
return scene.hasComponent(id);
}
template<typename T>
void removeComponent(unsigned int id) {
removeComponent(id);
}
// ...
};
Since the Component class is the only friend to Scene, only it can call private member functions. Since all those newly defined functions in Component are protected, only class that extends from Component can call those. They are invoked like this:
class Scriptable : public Component {
void foo() {
hasComponent<Bar>(87); // works, call function defined in `Component`
}
};
A tricky question. If would like to write a function that returns a pointer to some IFoo object, is it possible to prevent the assignment of this pointer?
I do not want to make IFoo a singleton and I can hide or delete the copy and assignment operators, but does C++ actually allow a pattern, where I explicitly have to call somebody else to obtain an object?
The background question is: I am thinking about some sort of dependency container, where you should always ask the container to get some IFoo * (pointer for the sake of polymorphism). The user should never be able to save it to some local variable or member to avoid a stalled reference to it. (For scenarios where the container is instructed to return no longer Foo, which is derived from IFoo but Bar)
Edit for clarification, although user R Sahu already said that is not possible.
Indeed the example of Mark B was a perfect illustration of what I wanted to prevent:
IFoo* foo_ptr_I_will_keep_forever = obj->getIFoo();
When I wouldn't have interfaces but only explicit instance of types I could return a reference, which given a private operator= and copy ctor would suffice.
Your title says:
Is there a way to prevent assignment of pointers?
No, you can't prevent that if your function returns a pointer.
However, if you return a handle, which can be a pointer to a type that is only forward declared or an integral value that can be used to come up the real object, and make sure that all the real functionality works with the handle, then you can have more freedom over when you can delete the real object without the risk of leaving the client code with a dangling pointer.
Here's a simple program that demonstrates the concept.
#include <iostream>
#include <set>
// Foo.h
struct Foo;
using FooHandle = Foo*;
FooHandle createFoo();
void fooFunction1(FooHandle h);
void fooFunction2(FooHandle h);
// Test Program
int main()
{
FooHandle h = createFoo();
fooFunction1(h);
fooFunction2(h);
fooFunction1(h);
return 0;
}
// Foo implementation.
namespace FooImpl
{
std::set<Foo*>& getLiveFooObjects()
{
static std::set<Foo*> liveObjects;
return liveObjects;
}
bool isValid(Foo* h)
{
return (getLiveFooObjects().find(h) != getLiveFooObjects().end());
}
}
using namespace FooImpl;
struct Foo {};
FooHandle createFoo()
{
FooHandle h = new Foo{};
getLiveFooObjects().insert(h);
return h;
}
void fooFunction1(FooHandle h)
{
if ( isValid(h) )
{
std::cout << "In fooFunction1.\n";
}
else
{
std::cout << "Ooops. The handle is no longer valid.\n";
}
}
void fooFunction2(FooHandle h)
{
std::cout << "In fooFunction2.\n";
delete h;
getLiveFooObjects().erase(h);
}
Output:
In fooFunction1.
In fooFunction2.
Ooops. The handle is no longer valid.
Give them back an object (that they can store if they want) that always looks up the real one via private (friend) interfaces.
For example, an IFooCaller that implements IFoo by getting the current IFoo and forwarding all calls to it.
A middle ground answer that would prevent accidentally storing a pointer to a particular implementation, but wouldn't prevent someone from doing it on purpose:
template <typename T> class service_wrapper;
class service_manager
{
template <typename T> friend class service_wrapper;
public:
template <typename T>
service_wrapper<T> get() const;
private:
template <typename T>
T* get_instance() const;
};
template <typename T>
class service_wrapper
{
friend class service_manager;
public:
T* operator->() const;
private:
service_wrapper(service_manager const & p_sm) : sm(p_sm) { }
service_manager const & sm;
};
template <typename T>
T* service_wrapper<T>::operator->() const
{
return sm.get_instance<T>();
}
Your manager only dispenses instances of service_wrapper<T>. The operator-> implementation allows invoking on the service using wrapper->method(...);, and always fetches the implementation pointer from the service manager.
This can be circumvented like:
T *ptr = sm.get<T>().operator->();
But that's not something you can accidentally do.
Lets say I have a class that has a data member that is a pointer to an abstract class Foo. One of the class's setters, setFoo asks for pointer to one of Foo's subclasses. What the programmer is supposed to pass is a new object of the subclass like setFoo(new FooBar(5, 10)); So that FooContainer is the only one holding a reference to the object and is the only one responsible for deleting that object. An example would be like...
class FooContainer final {
public:
FooContainer() : currentFoo(nullptr) {}
~FooContainer() {
delete currentFoo;
}
//Setter
void setFoo(Foo *foo) {
if (currentFoo != nullptr)
delete currentFoo;
currentFoo = foo;
}
//test that it holds the class
void fireFoo() {
currentFoo->func();
}
private:
Foo* currentFoo;
};
This has some big pitfalls like if I do these.
int main() {
FooContainer fc1;
holder.setFoo(nullptr); //Error passing a null pointer
holder.fireFoo();
//---
FooContainer fc2;
Foo* fooBar = new FooBar(5, 10);
holder.setFoo(fooBar); //Error now two objects hold references to fooBar
holder.fireFoo();
delete fooBar; //Error
return 0;
}
The solution I came up with was to use a variadic template function to set foo where it's passed the foo subclass type and varargs to construct whatever the new Foo subclass is, like this.
template <typename T, typename... Args>
void setFoo(Args... args) {
currentFoo = new T(std::forward<Args>(args)...);
};
So now I can do setFoo<FooBar>(5, 5); which insures that currentFoo is not a null pointer and the FooContainer is the only reference holder. Is this be the correct way to go about this? I've never encountered a problem like this before, and If I'm getting something wrong I can always fall back to unique pointers.
For ownership, you should use one smart pointer
Then you may use setter (which allows easily to have polymorphic Foo):
class FooContainer final {
public:
void setFoo(std::unique_ptr<Foo> foo) { // may be empty
currentFoo = std::move(foo);
}
void fireFoo() {
// may be empty if not set (constructor doesn't feed it) or set with nullptr
if (currentFoo) {
currentFoo->func();
}
}
private:
std::unique_ptr<Foo> currentFoo;
};
or internal factory (which ensures that you always have value)
class FooContainer final {
public:
template <typename...Ts>
explicit FooContainer(Ts&&... args) {
currentFoo = std::make_unique<Foo>(std::forward<Ts>(args));
}
template <typename...Ts>
void createFoo(Ts&&... args) {
currentFoo = std::make_unique<Foo>(std::forward<Ts>(args));
}
void fireFoo() {
assert(currentFoo); // Cannot be nullptr (except after moved currently ;) )
currentFoo->func();
}
private:
// You may even use `Foo currentFoo;` (which some changes above) if relevant
// (think about copy/move)
std::unique_ptr<Foo> currentFoo;
};
I want to create a guard, which locks a function on construction and unlocks it on destruction, e.g. calling the function with false and true.
class A {
void enable( bool flag );
};
within another method, I want to use:
A::anotherMethod( ... ) {
block_guard(A::enable); // now A::enable(false)
// some operation
} // now A::enable(true)
my ideas:
using template
template < class T >
class block_guard {
T t_;
public:
block_guard( T& t ) : t_(t) {
t_(false);
}
~block_guard() {
t_(true);
}
};
the question is, how to instantiate the template? maybe with boost::bind?
using boost::function
class block_guard {
typedef boost::function< void (bool) > T;
T t_;
public:
block_guard( T& t ) : t_(t) {
t_(false);
}
~block_guard() {
t_(true);
}
};
this works fine, but the call seems to be very complicated with
block_guard bg(boost::function< void (bool) >(boost::bind(&A::enable, pointer-to-A, _1));
any ideas?
maybe there is another, much simpler way?
First, realize that the member function is not all you need; you also need the object to invoke it on. There is no way in C++ for an object created in a function to implicitly capture the current this pointer.
I'm going to assume you don't have C++11 available. If you do, using your second solution with a lambda expression is easiest.
Now, if you don't care about the slight performance hit of boost::function (and you shouldn't), the second solution is good, but I would modify it slightly to make it more convenient to use by pulling the bind into the constructor.
class block_guard {
typedef boost::function< void (bool) > block_fn;
block_fn block_fn_;
public:
// For non-member functions and function objects:
template <typename Fn>
block_guard(Fn fn) : block_fn_(fn) {
block_fn_(false);
}
// For member functions:
template <typename T, typename Ret>
block_guard(T* obj, Ret (T::*fn)(bool)) : block_fn_(boost::bind(fn, obj, _1)) {
block_fn_(false);
}
~block_guard() {
block_fn_(true);
}
};
Usage:
block_guard guard(this, &A::enable);
I use a Ret parameter here because there's no reason not to allow functions that return something - the return value will simply get ignored.
If you don't want boost::function, the thing will get less easy to use, because you have to template the block guard. It becomes useful to make a block_guard specifically for member functions then. You also lose the ability to use non-void functions.
template <typename T>
class block_guard {
typedef void (T::*block_fn)(bool);
T* obj_;
block_fn block_fn_;
public:
block_guard(T* obj, block_fn fn) : obj_(obj), block_fn_(fn) {
(obj_->*block_fn_)(false);
}
~block_guard() {
(obj_->*block_fn_)(true);
}
};
Usage:
block_guard<A> guard(this, &A::enable);
Yes, there is a much simpler way, forget templates, generic thing and whatever not necessary and focus on the task.
All you need is a class with a ctor and a dtor. Write the dtor first, it reveals what you will need to work. Then write the ctor, taking arguments as needed. Lastly make the unwanted functions deleted (cctor, op=). Done.
Not generic, but straight to the point.
C++ has so much stuff that I don't know.
Is there any way to create a function within a class, that will always be called whenever any other function of that class is called? (like making the function attach itself to the first execution path of a function)
I know this is tricky but I'm curious.
Yes-ish, with a bit of extra code, some indirection and another class and using the -> instead of the . operator.
// The class for which calling any method should call PreMethod first.
class DogImplementation
{
public:
void PreMethod();
void Bark();
private:
DogImplementation(); // constructor private so can only be created via smart-pointer.
friend class Dog; // can access constructor.
};
// A 'smart-pointer' that wraps a DogImplementation to give you
// more control.
class Dog
{
public:
DogImplementation* operator -> ()
{
_impl.PreMethod();
return &_impl;
}
private:
DogImplementation _impl;
};
// Example usage of the smart pointer. Use -> instead of .
void UseDog()
{
Dog dog;
dog->Bark(); // will call DogImplementation::PreMethod, then DogImplementation::Bark
}
Well.. something roughly along those lines could be developed into a solution that I think would allow you to do what you want. What I've sketched out there probably won't compile, but is just to give you a starting point.
Yes. :-)
Wrap the object in a smart pointer
Invoke the object's special function automatically from the smart pointer's dereferencing operators (so that the special function is invoked whenever a client dereferences the smart pointer).
You can derive from this class template:
namespace detail {
struct const_tag;
struct nonconst_tag;
/* T is incomplete yet when pre_call is instantiated.
* so delay lookup of ::impl until call to operator->
* happened and this delay_lookup is instantiated */
template<typename U, typename>
struct delay_lookup;
template<typename U>
struct delay_lookup<U, nonconst_tag>
{
typedef typename U::template get_impl<
typename U::derived_type>::type impl_type;
impl_type* u;
delay_lookup(impl_type* u):u(u) { }
impl_type* operator->() { return u; }
};
template<typename U>
struct delay_lookup<U, const_tag> {
typedef typename U::template get_impl<
typename U::derived_type>::type const impl_type;
impl_type* u;
delay_lookup(impl_type* u):u(u) { }
impl_type* operator->() { return u; }
};
} // detail::
template<typename T>
struct pre_call {
private:
friend class detail::delay_lookup<pre_call, detail::const_tag>;
friend class detail::delay_lookup<pre_call, detail::nonconst_tag>;
typedef T derived_type;
/* pre_call is the friend of T, and only it
* is allowed to access T::impl */
template<typename U> struct get_impl {
typedef typename U::impl type;
};
protected:
typedef boost::function<void(T const&)> fun_type;
fun_type pre;
template<typename Fun>
pre_call(Fun pre):pre(pre) { }
public:
/* two operator->: one for const and one for nonconst objects */
detail::delay_lookup<pre_call, detail::nonconst_tag> operator->() {
pre(*get_derived());
return detail::delay_lookup<pre_call,
detail::nonconst_tag>(&get_derived()->d);
}
detail::delay_lookup<pre_call, detail::const_tag> operator->() const {
pre(*get_derived());
return detail::delay_lookup<pre_call,
detail::const_tag>(&get_derived()->d);
}
private:
T * get_derived() {
return static_cast<T *>(this);
}
T const* get_derived() const {
return static_cast<T const*>(this);
}
};
And use it like this:
struct foo : pre_call<foo> {
private:
/* stuff can be defined inline within the class */
struct impl {
void some() const {
std::cout << "some!" << std::endl;
}
void stuff() {
std::cout << "stuff!" << std::endl;
}
};
void pre() const {
std::cout << "pre!" << std::endl;
}
friend struct pre_call<foo>;
impl d;
public:
foo():pre_call<foo>(&foo::pre) { }
};
int main() {
foo f;
f->some();
f->stuff();
// f.some(); // forbidden now!
}
Previously i had a version that called post functions too. But i dropped it. It would have needed additional work. However, i would still not recommend you to do this "call function automatically" thingy. Because one can easily forget to use the operator-> syntax and just use the dot - and suddenly have the pre function not called
Update: The version above takes care of that, so one cannot accidentally call functions with the dot anymore.
There is no "automatic" way to do this. You would need to add a call to the function in each class method.
Without some insane code injection, this is not possible. However, you can of course call that function manually.
The short answer: No.
The long answer: there is no such thing in the C++ standard.
If I'm not mistaken this is a feature of what is called Aspect Oriented Programming.
As others have said, there is no "automatic" way to do this. As in, the C++ standard does not define a way to do this.
However, if you are going to go the route of putting a method call at the beginning of every method, I would recommend you instead store and invoke a method pointer instead. This will allow you to dynamically modify which method is being called, including none with some careful programming and setting the method to null.
I'm not sure exactly what your restrictions are, so I don't know if this helps.
If your object a singleton, you could stick all the code that gets called for every function call in the call to get the singleton.
Downside is all your other functions calls get ugly. And you may not be able to make the object a singleton.