I'm working on a class library in VC++ that shall have ref classes and some native code. Now, I need to use five native objects from an external framework. those objects must be declared on the heap NOT on the stack. I want encapsulate those objects in some sort of a structure knowing that constructors need to be called.
Thank you.
I'm not sure I know exactly what you're asking. Constructors always need to be called on objects whether they are on the heap or the stack. If you meant that you want something to automatically call destructors for heap allocated memory, then you can use either std::auto_ptr or boost::shared_ptr. Note that these are not equivalent so read the documentation! Auto pointers cannot be used in standard containers as they do not have the copy semantics necessary, while boost::shared_ptr can as it counts references as it copies.
To answer your more general question of declaration best-practices, you want to only fully declare objects that you need to and forward declare when you can. For example, if you have a class like:
// In X.h
class MyConfig;
class X
{
X(const MyConfig &config);
private:
const MyConfig &config;
};
// In X.cpp
#include "MyConfig.h"
X::X(const MyConfig &config) : config(config)
{
}
Here you do not need to full declaration contained in MyConfig.h within the X.h header file. You can do this b/c you do not need to know the size of the MyConfig object to construct class X as it only contains a reference which is the same size regardless of what the underlying object is. Doing this will help with dependencies and will also reduce compile times.
If on the other hand the private member config was changed to const MyConfig x; then you would have to include the MyConfig.h header in X.h because to construct class X requires knowledge of how much memory to allocate to store a MyConfig object.
Well, for each unmanaged class X, declare a ref class XWrapper that stores the unmanaged pointer to X privately, new's in constructor, and delete's in destructor. Why not?
You should wrap a shared_ptr like this:
template <class T>
class my_object_wrapper
{
boost::shared_ptr<T> ptr; // or std::tr1::shared_ptr<T> if available
public:
my_object_wrapper()
: ptr(new T)
{
}
boost::shared_ptr<T> ptr() const { return ptr; }
}
You could also use the pheonix approach:
template <class T>
class my_object_wrapper
{
boost::shared_ptr<T> ptr; // or std::tr1::shared_ptr<T> if available
public:
my_object_wrapper()
{
}
boost::shared_ptr<T> ptr()
{
if (ptr == null)
ptr = new T;
return ptr;
}
}
Related
I'd like to create a class with a statically declared array. I'd like to extend the class that basically changes the size of the array in the derived class. Everything else would stay the same.
namespace someNameSpace {
const uint8_t STATIC_ARRAY_SIZE = 50; // <-- change this value in a derived class?
class BaseClass {
private:
int some_array[STATIC_ARRAY_SIZE];
public:
void some_function_that_uses_above_array(){ ... };
}
}
Is there a way to do this without using templating? (I need the arrays to be allocated memory at compile time).
You can use template meta-programming for this:
namespace someNameSpace {
template <size_t STATIC_ARRAY_SIZE>
class BaseClass {
private:
int some_array[STATIC_ARRAY_SIZE];
public:
void some_function_that_uses_above_array(){ ... };
}
class Derived : public BaseClass<42> {
...
}
}
If you want to allocated at compile time, it is mean not dinamically allocated i think the solution you want still is template. At compile time for each different template parameter the compiler will generate a copy of class.
Example:
With #sturcotte06 code, if you declare in someplace BaseClass<10> or BaseClass<20>, for each parameter 10 and 20, the compiler will copy the code of class and apply the parameter like a #define.
In this link search for "PrintTwice function with int and double", there is a pratical example.
If you can't use template because of restrictions, i don't recommend but you can pass the array through constructor as a smart pointer, to avoid null reference is important check pointer on costructor and take a care on destructor.
After publicly inheriting enable_shared_from_this and initialzing the object of class, while calling another function of that class, i can still see empty weak pointer of enable_shared_from_this_class while debugging in Visual Studio.
All existing questions are due to either privately inheriting from enable_shared_from_this or calling weak_from_this in constructor. This is not the case for me. I am currently using c++ catch framework to test this scenario in visual studio debugger. In Initialize function, i can see, that weak_ptr of this object is empty.
header File :
template <typename T>
class IInfo
public:
IInfo()
{}
virtual ~IInfo()
{}
virtual bool RegisterForChange(FUNC_PTR<T> Callback, std::weak_ptr<T>) = 0;
};
template <typename T>
class Info : public IInfo<T>, public std::enable_shared_from_this<Info<T>>
{
public:
Info() {}
~Info() {}
virtual bool RegisterForChange(FUNC_PTR<T> Callback, std::weak_ptr<T> callerContext) override
{
//Some code
_callerContext = callerContext;
}
private:
std::weak_ptr<T> _callerContext;
};
class Env : public std::enable_shared_from_this<Env>
{
public:
Env();
bool Initialize();
static void func(/ some arguments / );
private:
std::shared_ptr<Info<Env>>_spInfo;
//other variables
}
Cpp File :
Env::Env() : _spInfo() // + other variables in initializer list
{
_spInfo = std::make_shared<Info<Env>>();
}
bool Env::Initialize()
{
_spInfo->RegisterForChange(FUNC_PTR<Env>func, this->weak_from_this());
}
TEST CASE : (used cpp catch framework)
Env env;
env.Initialize();
EDIT:
As per comments , asking it correcty, the Env module will be managed by a plugin which will create a unique_ptr and call Initialize.
Something like:
template<typename T>
std::unique_ptr<T> BringUp()
{
std::unique_ptr<T> ptr(std::make_unique<T>());
if (ptr && ptr->Initialize())
return std::move(ptr);
}
std::unique_ptr<Env> _envPtr;
_envPtr = BringUp<Env>();
I still face the same issue.
How shall i manage Env in this case?
Your construction code is still wrong. For shared_from_this to work, the object's lifetime has to be managed by shared pointers. First you tried managing it by scope and then you tried managing it with a unique pointer. Neither of those will work.
The point of shared_from_this is to allow an object's lifetime to be extended by code that needs to extend it. For that to work, the object's lifetime has to be managed by some structure that makes it possible for objects to extend its life. A scope can't do that because when the scope ends the object's memory is released. A unique_ptr can't do that because only one pointer to the object can exist at any time, so there's no way to extend its life as that would require two pointers (one would have to already exist or it would be dead and the one extending its life would be another).
Construct the Env object using std::make_shared and store a std::shared_ptr to it.
template<typename T>
std::shared_ptr<T> BringUp()
{
std::shared_ptr<T> ptr(std::make_shared<T>());
if (ptr && ptr->Initialize())
return std::move(ptr);
}
std::shared_ptr<Env> _envPtr;
_envPtr = BringUp<Env>();
I cannot figure a way to do this in the general case. Say that I have 2 classes and they maintain pointers to each other:
class first {
unique_ptr<second> p2;
public:
first() : p2(this) {}
};
class second {
first* p1;
public:
second(first* arg) : p1(arg) {}
};
This all works fine and dandy, but what I really want is to use a shared_ptr as a part of second because second objects may also be created independently of first. They will just be passed a pointer to a first on construction, but they won't know if it's gone.
I can't just make second::p1 a shared_ptr because I wouldn't know how to pass in this from first::first().
Is there an idiom that can help me handle this?
It is possible with the caveat that you can then only create instances on the heap. Using std::shared_from_this would be a nice solution but it can only be called once a std::shared_ptr to the object exists which is not possible until the constructor has finished, even when using std::make_shared and a std::bad_weak_ptr exception is thrown.
Instead we ensure that the only way to create an instance of this class is through a static function which does the necessary setup.
#include <cassert>
#include <memory>
class second;
class first {
struct Unconstructable {};
std::unique_ptr<second> p2;
public:
first(Unconstructable) : p2() {}
static std::shared_ptr<first> create() {
Unconstructable u;
auto f = std::make_shared<first>(u);
f->p2 = std::make_unique<second>(f);
return f;
}
};
class second {
std::shared_ptr<first> p1;
public:
second(std::shared_ptr<first> arg) : p1(arg) {}
};
int main()
{
auto f = first::create();
}
Edit: The use of Unconstructable isn't really necessary but is required for the use of std::make_unique. If I were to simple make the constructor private then std::make_unique would fail to compile even if I made it a friend function since the implementation uses internal helper functions. Having a private struct as a constructor argument is a way to bypass this while still preventing construction from happening outside of the class itself.
Copying from my comments as OP indicated this is an answer he is OK with.
Unfortunately, there is no safe way of doing so - for the simple matter of constructor not having a slightest idea how an object was allocated. What if it was not allocated dynamically at all?
enable_shared_from_this, as indicated in another comment, is not a solution either - it just allows to get a shared_ptr from a weak_ptr hidden inside the class. However, this is only safe as long as there is at least one shared_ptr already created and holding the lock - and again, this is not something which can be ensured from the constructor.
This question already has answers here:
How can I safely (and easily) count *all* instances of a class within my program?
(2 answers)
Closed 7 years ago.
I want to call all object exist in a project. how can i do that?
Class1 Abc;
Class1 Xyz;
Class1 asd[100];
for each (Class1 k in ???)
{
k.dosomething();
}
C++ has no notion of "project", so there's no formally correct answer as to how to call a method on all objects of a given class in a project.
Possibly you mean in a "program".
One way is to register a pointer to each object in a global set of such object pointers. A main problem with that is that ideally it's the constructor that has to do the registering job, and the constructor doesn't know if this object will end up as const. And so you can inadvertently end up calling a modifier method on a const object.
One (limited) solution is to have do_something as const method, when that's practical.
Another (general but more complex) solution is to restrict creation of objects of that class to factory functions, because a factory function can register an object after it's turned const after successful construction.
C++ doesn't have type introspection, so it's impossible.
You can solve it by storing all object of Class1 in a container, and then iterate over that. For example, you could have a static member variable, a vector, and in the constructor you simply add this to the vector. It only works for that single class though, and there's no good or standard way to generalize it.
There are libraries that can add simple type introspection functionality, but it always requires you to add extra code to your classes, and usage of macros.
C++ language does not support this but you can implement it as an object pool pattern. This pattern is especially useful for efficient memory management and economical usage of memory and other resources in tightly constrained environments, where even small performance gains are of vital importance.
You can use Curiously recurring template patterns to inherit from a class which updates a container including all the classes for you.
#include <iostream>
#include <unordered_set>
template <typename T>
class IterableType{
public:
std::unordered_set<T const*>& allClasses(){
return classes_;
}
protected:
IterableType(){
IterableType<T>::classes_.insert(static_cast<T*>(this));
}
IterableType(const IterableType<T>& t){
IterableType<T>::classes_.insert(static_cast<T*>(this));
}
IterableType(const IterableType<T>&& t){
IterableType<T>::classes_.insert(static_cast<T*>(this));
}
IterableType<T>& operator=(const IterableType<T>& t){
return *this;
}
IterableType<T>& operator=(const IterableType<T>&& t){
return *this;
}
~IterableType(){
IterableType<T>::classes_.erase(static_cast<T*>(this));
}
private:
static std::unordered_set<T const*> classes_;
};
template <typename T>
std::unordered_set<T const*> IterableType<T>::classes_;
The constructor and destructor are protected as they are only supposed to be called from the derived classes. As the set is declared with const members it will never allow to modify const classes. However, if you want to modify them in them while iterating you need to use const_cast or remove the const from declaration. But as said these would allow the modification of const objects.
To use this you just inherit from this class using the child class as a template argument.
class Class1:public IterableType<Class1>{
public:
Class1(int n):n_(n)
{}
void print() const{
std::cout << n_ << std::endl;
}
private:
int n_;
};
int main(){
Class1 a(3),b(7),c(8);
for (auto i:a.allClasses()){
i->print();
}
return 0;
}
Edit: Implemented copy and move constructors and made the set const
I am creating a bunch of C structs so i can encapsulate data to be passed over a dll c interface. The structs have many members, and I want them to have defaults, so that they can be created with only a few members specified.
As I understand it, the structs need to remain c-style, so can't contain constructors. Whats the best way to create them? I was thinking a factory?
struct Foo {
static Foo make_default ();
};
A factory is overkill. You use it when you want to create instances of a given interface, but the runtime type of the implementation isn't statically known at the site of creation.
The C-Structs can still have member functions. Problems will, however, arise if you start using virtual functions as this necessitates a virtual table somewhere in the struct's memory. Normal member functions (such as a constructor) don't actually add any size to the struct. You can then pass the struct to the DLL with no problems.
I would use a constructor class:
struct Foo { ... };
class MakeFoo
{
Foo x;
public:
MakeFoo(<Required-Members>)
{
<Initalize Required Members in x>
<Initalize Members with default values in x>
}
MakeFoo& optionalMember1(T v)
{
x.optionalMember1 = v;
}
// .. for the rest option members;
operator Foo() const
{
return x;
}
};
This allows to arbitrary set members of the struct in expression:
processFoo(MakeFoo(1,2,3).optionalMember3(5));
I have an easy idea, here is how:
Make the structure, just like you normally would, and create a simple function that initializes it:
struct Foo{...};
void Default(Foo &obj) {
// ... do the initialization here
}
If you have multiple structures, you are allowed in C++ to overload the function, so you can have many functions called 'default', each initializing its own type, for example:
struct Foo { //... };
struct Bar { //... };
void Default(Foo &obj) {...}
void Default(Bar &obj) {...}
The C++ compiler will know when to call the first or the second overload based on the parameter. The & makes obj a reference to whatever parameter you give it, so any changes made to obj will be reflected to the variable you put as parameter.
Edit:
I also have an idea for how to specify some parameters, you can do it by using default parameters. This is how it works:
For example you the following function; you can specify default values for parameters like this:
void Default (Foo &obj, int number_of_something = 0, int some_other_param = 10)
{ ... }