Can one somehow retrieve the "host instance" from a private class? - c++

I have the following setup (simplified):
class A {
public:
void doBar() { B b; b.bar(); }
private:
int foo;
class B {
public: void bar() { /* do somehting with foo */ }
};
};
Now, VS tells me:
A non static member reference must be relative to a specific object
Well, okay, that sounds reasonable. However, as this class B is private to A I can be sure that it will never be used outside of an instance of a (specific) instance of A (okay, static methods of A are an exception).
So bottom line, is there any chance to get the current instance of A from a method of B, i.e., the instance from which B b was instantiated? I'm especially looking for a clean solution because otherwise I'd just pass in a reference.

Declaring a class within another class doesn't create "containment", only scope of the class declaration. Your B objects are not - generally speaking - contained by A objects, unless you make them so by virtue of how you hold references to each other.
So, no; there is no mechanism by which a B is able to determine which instance of A created it, because there is nothing special about this situation.
And think about it: the B object is created on the stack in your example, but it could have been heap-allocated. The A object might have also been created on the heap with 'new', or on the stack, or on a custom heap, or via 'placement-new'. There is no relation at all between the two objects in memory.

Related

Is there a way to dynamically change an object to another type?

Let's say I have a class A that inherits from its parent class B, and there is another class C that also inherits from class B. Is there a way to change this pointer of class A to class C at run time?
class A : public B {
A::someFunction() {
//can I change this pointer to class C here?
}
}
class C : public B {
...
}
You cant and you shouldn't. The reason is pretty simple. Take a look at this code,
class Base {
public:
Base() {}
virtual void SayHello() {}
};
class A_Derived : public Base {
public:
A_Derived() {}
virtual void SayHello() override { ... }
void SayAllo() { ... }
};
class B_Derived : public Base {
public:
B_Derived() {}
virtual void SayHello() override { ... }
void SayBello() { ... }
};
Now when is we assign the A_Derived class pointer to B_Derived, the compiler will allow to call the SayBello method. This is because for the compiler, its a B_Derived class pointer, it doesn't know about the actual pointer data is pointing at a data block of A_Derived (because inheritance is not compile time, its runtime). So what happens when you call SayBello using that pointer? Its gonna be undefined behavior. You see the issue?
This is why you cant do it (logically and also using C++ style casting).
Is there a way to dynamically change an object to another type?
No. The type of an object cannot change through its lifetime.
Let's say I have a class A that inherits from its parent class B, and there is another class C that also inherits from class B. Is there a way to change this pointer of class A to class C at run time?
No.
At best, you could destroy the original object, and reuse its memory to create another object. Obviously the size and alignment of the memory must be sufficient for the new type. Any reference (which includes pointers such as this in a member function) to the old object will have been invalidated by the destruction of the original object. Reuse of storage is an advanced topic which I don't recommend to beginners.
There is no valid way to do this for one simple reason - in your class inheritance structure, an object of class A cannot be also an object of class C. In C++, two objects of different types can have the same address if and only if one of the objects is a subobject of the other, which is not your case. If you cast a pointer to A to a pointer to C, the pointer will still refer to an object of type A, and dereferencing the casted pointer would result in undefined behavior.
Most probably, what you want to do is to create an object of class C from an object of class A. You can use a converting constructor or a conversion operator to implement this.
Note that if what you really want is to reuse the storage allocated for the object of type A, you will still need to destroy the object A first and then construct the object C. You will have to save any relevant data from A before destroying it to be able to construct C with the data.

C++ Constructor member initializer lists, Object Slicing

I have two classes
class A {
public:
virtual void doStuff() = 0;
};
class B : public A {
int x;
public:
virtual void doStuff() override { x = x*2;} //just example function
};
And another class that modify and use data from the previous
class Foo {
A a;
public:
Foo::Foo(A &a_) : a(a_) {}
};
now I create the objects, and passes to the Foo class
B b;
// edit b attributes,
Foo foo(b);
So at the argument list for the class constructor I know there is not the problem of object slicing, because is a reference, but what is the case at the moment of assign the variable a(a_)?
Since I don't know how much time the object b is going to live I need to make a secure copy. I have a lot of different derived classes from A, even derived from the derived.
Will there be a object slicing?,
Is there a solution to this, or I need to pass pointers (don't want this approach)?
This causes slicing. C++ built in polymorphism only works with pointer/reference semantics.
In fact:
class Foo {
A a;
that won't even compile, because A is not a concrete class.
To fix this, first make virtual ~A(){}; and then pass smart pointers to A around. Either unique or shared.
Failing that you can use your own bespoke polymorphism. The easiers way is to stuff a pImpl smart pointer as a private member of a class and implement copy/move semantics in the holding class. The pImpl can have a virtual interface, and the wrapping class just forwards the non-overridable part of the behaviour to it.
This technique can be extended with the small buffer optimization, or even bounded size instances, in order to avoid heap allocation.
All of this is harder than just using the built in C++ object model directly, but it can have payoff.
To see a famous example of this, examine std::function<Sig> which is a value type that behaves polymorphically.
There will be object slicing with what you currently have. You're calling the A copy-constructor in Foo's constructor, and there aren't virtual constructors.
Having a member variable of type A only reserves enough space within an instance of Foo for an instance of A. There is only dynamic binding with pointers and references (which are pointers under the hood), not with member variables.
You would have to use pointers to get around this or you could rethink whether you really need a set-up like this.
Yes, there is slicing.
There has to be slicing, because a B does not fit inside a A, but it is an A that you are storing inside the class Foo. The B part is "sliced off" to fit; hence the name.

C++: How to manage object lifetimes and dependencies?

A concrete problem:
I have a Main application which has objects of type A and type B (among other types).
Object of type B requires A object to be properly constructed (so there is a constructor
A(const B& b). However Main may change B object it holds at any time. How do I make
sure that when Main changes its B object then the A object's internal reference is changed ?
In general, what are some good practices to manage object lifetimes, where objects
have dependencies ?
If A never caches any of B properties, and always references the instance of B it holds to generate any dependent output, any changes that are made to B should be reflected in subsequent calls to A. I am assuming you're simply storing a reference to B within the constructor and not creating a local copy.
If I understand correctly, you want to not just change the B object but completely replace it with a different B. References can't be changed once created, so you'll want to use pointers instead.
You may want to use the Observer Pattern to let the A objects know when their B should be replaced: http://en.wikipedia.org/wiki/Observer_pattern
In general: Always make sure you know about the ownership. Whenever you create an object, wither another object needs to be the owner or it has to be a local variable. In your case the main routine would be the owner of the instance to B. If you have a reference to B in your A instance, A will see all changes to the instance - just make sure you do not copy (not having a reference does implicit copying). So in your code you would have something like
private:
const B& theReference;
or
private:
B& theReference;
if you need to call non-const methods (remember to also change your constructor in that case).
If I understood you correctly, if you make modifications to an object that main holds, it should in turn effect the object what A holds. For this you may take the help of constructor initializer.
#include <iostream>
class B{
public:
int num ;
B(int arg):num(arg) {}
};
class A{
public:
const B& ref ;
A( const B& arg ): ref(arg){}
};
int main()
{
B objOne(10) ;
A objTwo(objOne) ;
std::cout << objTwo.ref.num << std::endl ;
objOne.num = 20 ;
std::cout << objTwo.ref.num << std::endl ;
}
Output :
10
20
Keep in mind:
All problems can be solved with one more layer of indirection.
Object ownership must be obvious.
In your case, if the B instance can come-and-go at any time (the old instance is deleted, a new one is "newed"), then you can create a "utility handle" class that "wraps" the B instance:
class BHandle {
B* b_; // can change at any time
public:
....
};
Then, your A class would reference a BHandle instance, or wholly contain a BHandle instance. Then, B instances can come-and-go, but A::my_b_handle_ would always reflect where the "current" B instance is.
On the other hand, if the B instance merely has data members that change (its instance itself does not come-and-go), then you don't need to do anything (A will always reference the same B instance, and you may in some cases merely need to "notify" A that properties changed in the B object it references).
Here's how I handled the problem. User code looks like this:
class Env
{
public:
Env();
~Env();
private:
void *priv;
};
class MyInterface
{
public:
MyInterface(Env &e) : e(e) { }
int create_A();
void use_A(int a);
private:
Env &e;
void *priv;
};
int main()
{
Env e;
MyInterface i(e);
int a = i.create_A();
use_A(a);
}
This way every dependency is visible in the user code. The dependencies between objects are nicely stored inside a std::vectors in a Env class. Indexes to the vectors will be returned from the functions. create_A() and use_A() can communicate via ints. The objects will all be destroyed at the same time when Env class goes out of the scope. Your objects could be deriving from a base class which has virtual destructor.
If you have more than one int, recommended way is this:
struct ID { int i; };
Implementation of the interface would rely on the following functions:
A *find_a(const Env &e, ID i);
ID create_a(Env &e, A *ptr);
The above approach solves the following problems with object lifetimes:
lifetime of the objects
dependencies between the objects (via ints)
identifying the objects
the dependencies could be stored either via int's or via pointers
destroying the objects when lifetime ends

Passing another class amongst instances

I was wondering what is the best practice re. passing (another class) amongst two instances of the same class (lets call this 'Primary'). So, essentially in the constructor for the first, i can initialize the outside instance (lets call this 'Shared') - and then set it to a particular value whilst im processing this class in main().
So 'Shared', may be an int, say 999 by now.
Now what if i create another instance of the main class 'Primary'? whats the best way to access the already initialized outside instance of 'Shared' - because if i don't handle this correctly, the constructor for 'Primary', when called again will just go ahead and create one more instance of 'Shared', and thus i loose the value 999.. i can think of some messy solutions involving dynamic pointers and if statements (just) but i have a feeling there might be a simpler, cleaner solution?
As I understand it:
You have a class A
You have a class B
For all members of class A there is a single instance of class B
You did not mention if any parameters from the A constructor are used to initialize B!
What happens to the parameters of the second A that are used for B?
So we will assume that B is default constructed.
We will also assume that you need the instance of B to be lazily evaluated otherwise you would just use a static member.
class A
{
B& bRef;
public:
A()
:bRef(getLazyB()) // Get a reference to the only B for your object.
{}
private:
static B& getLazyB()
{
static B instance; // Created on first use
return instance; // returned to all users.
}
};
Make the constructor take a pointer or reference to the shared class. It is easier to construct outside.
class Shared;
class Same
{
shared& shared_;
Same( Shared& s ) { shared_ = s; }
}
With appropiate use of const and other constructors etc.
This depends on the semantics of your classes. If the outside class is not really outside but some obscure implementation detail that happens to be shared between instances, pass the first instance to the constructor of the second instance and get a reference to the outside instance there.
If the outside class is really an outside class with a meaning by itself, create it outside and pass it to the constructor just as Mark suggested.
If not only two specific instances but all instances share the same instance of the outside class, think about making it a static member of the class, as Martin York suggested.

Factory method pattern implementation in C++: scoping, and pointer versus reference

I've been looking at the example C++ Factory method pattern at Wikipedia and have a couple of questions:
Since the factory method is static, does that mean the newly created object won't go out of scope and have the destructor method called when the factory method exits?
Why return a pointer, as opposed to a reference? Is it strictly a matter of preference, or is the some important reason for this?
Edit 1: The more I think about it, both the reference and the pointer returned will stay in scope because they are referenced outside of the method. Therefore, the destructor won't be called on either one. So it's a matter of preference. No?
Edit 2: I printed out the destructor call on the returned reference, and it doesn't print until the program exits. So, barring further feedback, I'm going to go with the reference for now. Just so I can use the "." operator on the returned object.
Static method is one that can be called without having an instance of the factory. That has nothing to deal wtih the lifetime of the newly created object. You could use a non-static method with the same success. The factory method usually doesn't need any data from an existing object of the same class and therefor doesn't need an existing instance and this is why factorey methods are usually static.
You will use new to create the object that the factory will return. It's usual to return them by pointer. This shows explicitly that it's a new object ant the caller must take care of its lifetime.
I'm thinking there is a greater issue of understanding memory management. The factory method is allocating items on the heap (using new). Items on the heap never get automatically reclaimed (except by modern desktop OSs on process termination). The behavior you are describing is for items on the stack where they are reclaimed when you leave the local scope.
If you return a reference to an object that reference will become invalid when the method goes out of scope. This won't happen with a pointer, since the destructor isn't called.
It is true that static modifies when the value goes out of scope, but only if the variable is declared static, not if the method is declared static.
Your Wiki link says wrong.
There shouldn't be any static method. You can consider Factory Method as Template Method pattern that creates Objects. This method doesn't receive any "Name" parameter and create all the time same type of object.
Often, designs start out using Factory
Method (less complicated, more
customizable, subclasses proliferate)
and evolve toward Abstract Factory,
Prototype, or Builder (more flexible,
more complex) as the designer
discovers where more flexibility is
needed. [GoF, p136]
In the following example Business::makeObject is the factory method
class ObjectBase
{
public:
virtual void action() = 0;
virtual ~ObjectBase(){};
};
class ObjectFirst : public ObjectBase
{
public:
virtual void action(){ std::cout << "First"; }
};
class ObjectSecond : public ObjectBase
{
public:
virtual void action(){ std::cout << "Second"; }
};
class Business
{
public:
void SendReport()
{
std::auto_ptr< ObjectBase > object(makeObject());
object->action();
}
virtual ~Business() { }
protected:
virtual ObjectBase* makeObject() = 0;
};
class BusinessOne: public Business
{
public:
protected:
virtual ObjectBase* makeObject()
{
return new ObjectFirst();
}
};
class BusinessTwo: public Business
{
public:
protected:
virtual ObjectBase* makeObject()
{
return new ObjectSecond();
}
};
int main()
{
std::auto_ptr<Business> business( new BusinessTwo() );
business->SendReport();
return 0;
}
No. Static method - is almost same as global function in class namesapce and with access to private static variables;
Pointers usage is issue of createing objects in heap. They create object in heap for longer object lifetime than create-function scope;
EDIT:
I think wikipedia - is wrong in c++ example.
We have in exmaple - not same implementation as in class diagram or here (http://www.apwebco.com/gofpatterns/creational/FactoryMethod.html)
It will be better if you read about patterns from most trusted sources, e.g: Design Patterns: Elements of Reusable Object-Oriented Software.
The keyword static means different things on a method and on a variable. On a method as in the example it means that it is class global, and you need not have an instance of the class to call it.
To create a new object dynamically you need to use new, or 'a trick' is to assign a temporary object to a reference. assigning a temporary object to a point will not keep that object alive.
So you could do the following, but it is not normally done because you would often want to keep many things created from a factory, and then you would have to copy them rather than simply holding the pointer in a list.
class PizzaFactory {
public:
static Pizza& create_pizza(const std::string& type) {
if (type == "Ham and Mushroom")
return HamAndMushroomPizza();
else if (type == "Hawaiian")
return HawaiianPizza();
else
return DeluxePizza();
}
};
const Pizza &one = create_pizza(""); // by ref
Pizza two = create_pizza(""); // copied
EDIT
Sorry mistake in code - added missing const to ref.
Normally, a temporary object lasts only until the end of the full expression in which it appears. However, C++ deliberately specifies that binding a temporary object to a reference to const on the stack lengthens the lifetime of the temporary to the lifetime of the reference itself