Nested Classes in c++ - c++

class A{
public:
template<typename Obj>
class MyVec{
//some methods...
};
MyVec<A> a; //-> doesnt work
//vector<A> a; //using stl vector-> this works
};
class B{
public:
void someMethod();
private:
A::MyVec<A> b;
};
In the method, when I do sth like:
void someMethod(){
//...
b[0].a.pushback(element);
//...
}
In class A if i use std::vector everything works properly. But when i use nested class it doesn't work.

I've taken your code and modified it as minimally as possible to get something that compiles. This seems to work fine. And so the error is not in the code you have shown us.
#include <iostream>
#include <string>
class A
{
public:
template<typename Obj>
class MyVec{
public:
//My pushback just stores the value away for later.
void pushback(Obj & o )
{
if( obj )
{
*obj = o;
}
else
{
obj = new Obj(o);
}
std::cout<<this<<" : Pushing object "<<&o<<std::endl;
}
//some methods...
//My operator[] just returns the stored object.
Obj& operator[](int i) { return *obj; }
Obj * obj;
MyVec() : obj( NULL ) {}
};
MyVec<A> a;
};
class B
{
public:
B()
{
A an_a;
b.pushback(an_a); //Better store one away since we access it in someMethod.
}
void someMethod()
{
//...
A element;
b[0].a.pushback(element);
//...
}
private:
A::MyVec<A> b;
};
int main()
{
//Test that it all works
B outer;
outer.someMethod();
}
When I run this I get:
0xbffffa5c : Pushing object 0xbffffa0c
0x3ec3c0 : Pushing object 0xbffffa2c
Which is what I'd expect. (one push in the constructor of B and one push to the internal object from someThing)
You can view the result here:
http://ideone.com/BX8ZQ

You really should show the code inside MyVec. As a first guess, maybe MyVec's operator[] isn't returning a reference, so when you do b[0].pushback you're changing a copy instead of what you want; you wouldn't get that problem if you just tested with b.pushback()...

Related

C++ create static object without constructing it (without allocation)

Im writing embedded code that cannot use memory allocation!
Also, static objects (therefore constructed before the microcontroller has executed the main funtion with all its initialization) shall be constructed within the main after the initialization, not before.
The only solution people suggest is to use static object pointers and allocate (construct them with new) during initialization. since this is no option for me, is there no other solution?
what i wanna do is as follows:
class A
{
public:
A(int a, bool b)
: myVal1(a), myVal2(b)
{
}
private:
int myVal1;
bool myVal2;
}
class B
{
public:
B(char x)
: myChar1(x) // <-- NO CONSTRUCTION, NO PARAMETER OF MYOBJECTA
{
}
void init()
{
// now i wanna construct myObjectA
myObjectA(123, false);
}
private:
char myChar1;
A myObjectA; // <-- NO CONSTRUCTION, NO PARAMETER
}
static B myObjectB('F'); // <-- NO CONSTRUCTION, NO PARAMETER OF MYOBJECTA
void global_init()
{
// ... do before construction
// now i wanna construct myObjectA
myObjectB.init();
//... do after construction
}
You can use a storage area large enough to create there an instance of A and placement new to control the time you create it.
As an example:
#include
#include
struct A {
A(int a, bool b): myVal1(a), myVal2(b) {}
void foo() {}
private:
int myVal1;
bool myVal2;
};
struct B {
B(char x): myChar1(x) {}
~B() { if(ptr) { ptr->~A(); } }
void init() {
ptr = new (&storage) A{123, false};
}
A * myObjectA() {
return ptr;
}
private:
char myChar1;
std::aligned_storage_t<sizeof(A), alignof(A)> storage;
A *ptr{nullptr};
};
static B myObjectB('F');
void global_init() {
// ... do before construction
// now i wanna construct myObjectA
myObjectB.init();
//... do after construction
}
int main() {
global_init();
myObjectB.myObjectA()->foo();
}
This won't allocate memory (if I got right what you mean for that) and the instance of A is actually created within B::init (that seems to be a requirement from what you wrote in your question).
If you have access to a compiler that supports C++17 or you can use the C++ Boost Libraries, std::optional is a valid alternative as suggested in another answer. Anyway you didn't specify the revision of the standard to which to adhere, so... Here is a way to go in any case.
Do you have boost available?
#include <boost/optional.hpp>
class A
{
public:
A(int a, bool b)
: myVal1(a), myVal2(b)
{
}
private:
int myVal1;
bool myVal2;
};
class B
{
public:
B(char x)
: myChar1(x) // <-- NO CONSTRUCTION, NO PARAMETER OF MYOBJECTA
{
}
A& getA() {
assert(myObjectA);
return myObjectA.get();
}
void init()
{
// now i wanna construct myObjectA
myObjectA.emplace(123, false);
}
private:
char myChar1;
boost::optional<A> myObjectA; // <-- NO CONSTRUCTION, NO PARAMETER
};
static B myObjectB('F'); // <-- NO CONSTRUCTION, NO PARAMETER OF MYOBJECTA
void global_init()
{
// ... do before construction
// now i wanna construct myObjectA
myObjectB.init();
//... do after construction
}
int main()
{
global_init();
}

Convert class to derived class, without modifying it

I am working with a set of classes A, B, ... These classes are independent except that they have one method in common. Now I want to combine these classes in a vector, to call method in one loop. It seems that the best solution is to make the classes derived classes from some Parent (see below).
Now the question is the following. I want to create a header-only library for each class (a.h, b.h, ...). There I want the classes to be completely independent. Only in the main module I want to 'attach' the classes to a Parent to be able to combine them in a vector. How do I do this? Or do I have to resort to a vector of void* pointers? Or is there another way to combine these classes in a vector?
Classes in list: with parent/child paradigm
Here is what I have been able to do to combine the classes in the vector. Note I specifically want to avoid the parent/child paradigm in the class definitions. But I still want to combine them in a vector.
#include <iostream>
#include <vector>
#include <memory>
class Parent
{
public:
virtual ~Parent(){};
virtual void method(){};
};
class A : public Parent
{
public:
A(){};
~A(){};
void method(){};
};
class B : public Parent
{
public:
B(){};
~B(){};
void method(){};
};
int main()
{
std::vector<std::unique_ptr<Parent>> vec;
vec.push_back(std::unique_ptr<Parent>(new A));
vec.push_back(std::unique_ptr<Parent>(new A));
vec.push_back(std::unique_ptr<Parent>(new B));
for ( auto &i: vec )
i->method();
return 0;
}
Compile using e.g.
clang++ -std=c++14 main.cpp
A possible solution based on type erasure, static member functions and pointers to void that doesn't make use of virtual at all (example code, far from being production-ready):
#include <iostream>
#include <vector>
struct Erased
{
using fn_type = void(*)(void *);
template<typename T>
static void proto(void *ptr) {
static_cast<T*>(ptr)->method();
}
fn_type method;
void *ptr;
};
struct A
{
void method(){ std::cout << "A" << std::endl; };
};
struct B
{
void method(){ std::cout << "B" << std::endl; };
};
int main()
{
std::vector<Erased> vec;
vec.push_back(Erased{ &Erased::proto<A>, new A });
vec.push_back(Erased{ &Erased::proto<B>, new B });
for ( auto &erased: vec ) {
erased.method(erased.ptr);
}
return 0;
}
This can help to avoid using a common base class. See it on wandbox.
As mentioned in the comments, here is a slightly modified version that adds create and invoke methods to reduce the boilerplate for the users.
This is more of a pseudocode, trivial details are omitted.
struct HolderBase
{
virtual void foo() = 0;
};
template <class T>
struct Holder : HolderBase
{
Holder(T* t) : t(t) {}
T* t;
void foo() { t->foo(); }
};
std::vector<HolderBase*> v { new Holder<A>(new A), new Holder<B>(new B) };
You can also have a variant of Holder that holds an object by value (and mix both variants in the same vector freely).
If you have a single method to call, there is a much simpler solution:
A a;
B b;
std::vector<std::function<void()> v { [](){a.foo();}, [](){b.foo();} };
You want to erase the type of the objects and treat them uniformly, so naturally type erasure is the solution.
class with_method_t {
struct model_t {
virtual ~model_t() = default;
virtual void call_method() = 0;
};
template<class C>
class concept_t final : public model_t {
C obj;
public:
concept_t(C const& c) : obj{c} {}
concept_t(C&& c) : obj{std::move(c)} {}
void call_method() override { obj.method(); }
};
std::unique_ptr<model_t> instance;
public:
template<class C>
with_method_t(C&& arg)
: instance{std::make_unique<concept_t<C>>(std::forward<C>(arg))}
{}
void method() { instance->call_method(); }
};
Then have yourself a vector of with_method_t which is a value type. No raw dynamic allocation or de-allocation. The instance is build by forwarding the argument it receives into a small polymorphic container:
std::vector<with_method_t> vec;
vec.emplace_back(A{});
vec.emplace_back(B{});
for ( auto &i: vec )
i.method();

Is it possible to pass "this" by default?

Is it possible to pass this by default ?
Here is what I currently have
class A
{
public:
template<typename T>
void dowithT(T t) {}
};
class B
{
public:
A a;
B()
{
//Calling 'dowithT' with 'this'
a.dowithT(this);
}
};
This function requires passing this from the caller of the function every time. So I wondered if there is a way to encapsulate this task, so that you don't need to pass this to dowithT.
I tried to do something like this:
class A
{
public:
// '= this' doesn't compile
template<typename T>
void dowithT(T t = this) {}
};
class B
{
public:
A a;
B()
{
//Calling 'dowithT' without 'this'
a.dowithT();
}
};
Unfortunately, I can't use templates, so my first solution isn't an option.
Is this possible?
Edit: I gave a concrete answer with my own implementation below. Also with a few mor deatils of what I wanted in the end.
TL;DR No, this is not possible.
this is not the same type in every class, you can't generalize it, so no, not possible.
Additionally, what would this be if doWithT() was called from a non-member function? nullptr?
That's why it isn't possible. You have to use a template.
Instead of B having a member of type A, it can inherit from A, and use something like the "curiously recurring template pattern."
If you cannot make class A a template, you can still do it like so:
class A
{
protected:
template <class T>
void dowithT()
{
T* callerthis = static_cast<T*>(this);
// callerthis is the "this" pointer for the inheriting object
cout << "Foo";
}
};
class B : public A
{
public:
B()
{
dowithT<B>();
// Or A::dowithT<B>();
}
};
dowithT() must only be called by an inheriting class (hence I made it protected), with the template parameter the caller's own type, or you'll break everything.
You may achieve exactly what you want by using a private mixin class to provide the dowithT method that takes no arguments:
#include <iostream>
#include <typeinfo>
class A
{
public:
template<typename T>
void dowithT(T* t) {
std::cout << "Hello, World" << typeid(*t).name() << std::endl;
}
};
template<class Owner>
struct calls_a
{
void dowithT()
{
auto p = static_cast<Owner*>(this);
p->a.dowithT(p);
}
};
class B
: private calls_a<B>
{
friend calls_a<B>;
A a;
public:
B()
{
//Calling 'dowithT' with 'this'
dowithT();
}
};
int main()
{
B b;
}
No, it is not possible. There is nothing really special about this when used as an argument to a function taking T* (template or not), it's just a pointer like any other.
this A is different from this B. In your first code, this refers to the caller, while in the second this refers to the callee. Thus what you want to do isnt really possible.
Here's one possibility, which might, or might not suit your needs:
template<typename T>
class A
{
public:
A(T t) : t(t) {}
void dowithT()
{
cout << "Foo";
}
private:
T t;
};
class B
{
public:
A<B*> a;
B() : a(this)
{
a.dowithT();
}
};
You could use a private method in class B that acts as a relay, and use the constant nullptr as a special value for this, if you want to be able to pass other values:
class B
{
public:
A a;
B()
{
//Calling 'dowithT' with 'this'
innerdo();
}
private:
void innerdo(B *p = nullptr) {
if (p == nullptr) p = this;
a.dowithT(p);
}
};
If you only need to pass this it is even simpler
void innerdo() {
a.dowithT(this);
}
After trying out various things you mentioned, I'd like to give my answer/solution to the problem myself to clarify some details:
#include <iostream>
using namespace std;
#include <functional>
template <typename CallerType>
class AFunctionConstructor{
private:
virtual void abstr()
{}
public:
typedef void(CallerType::*CallerTypeFunc)();
function<void()>* constructFunction(CallerTypeFunc func)
{
CallerType* newMe = dynamic_cast<CallerType*> (this);
return new function<void()>(std::bind(func,newMe));
}
};
class A : public function<void()>
{
protected:
public:
A();
A(function<void()>* func) : function<void()>(*func)
{}
};
// now create ressource classes
// they provide functions to be called via an object of class A
class B : public AFunctionConstructor<B>
{
void foo()
{
cout << "Foo";
}
public:
A a;
B() : a(constructFunction(&B::foo)) {}
};
class C : public AFunctionConstructor < C >
{
void bar()
{
cout << "Bar";
}
public:
A a;
C() : a(constructFunction(&C::bar)) {}
};
int main()
{
B b;
C c;
b.a();
c.a();
cout << endl;
A* array[5];
array[0] = &b.a; //different functions with their ressources
array[1] = &c.a;
array[2] = &b.a;
array[3] = &c.a;
array[4] = &c.a;
for (int i = 0; i < 5; i++) //this usability i wanted to provide
{
(*(array[i]))();
}
getchar();
return 0;
}
Output :
FooBar
FooBarFooBarBar
This is as far as i can press it down concerning examples. But i guess this is unsafe code. I stumbled across possible other and simpler ways to achieve this (other uses of std::function and lambdas(which i might have tried to reinvent here partially it seems)).
At first I had tried to pass "this" to the bind function in function<void()>*AFunctionConstructor::constructFunction(CallerTypeFunc func)
,though, which i now get through the dynamic upcast.
Additionally the functionality of AFunctionConstructor was first supposed to be implemented in a Constructor of A.

How to do lazy construct in C++?

I want to make 'lazy construct' in a C++ class, a simple method to do that is something like this:
#include "b.hpp" // class B
class A {
public:
// invoke B() in b.hpp, this constructor do not actually do init
A(int v_in) : v(v_in) {}
void foo() {
if(flag == false) {
b = create_B_obj();
flag = true;
}
}
private:
B create_B_obj() {
// some expensive ops
//...
}
private:
bool flag = false;
B b;
int v;
};
But a existing problem is that B may not contain a default constructor (B()), so how can I do 'lazy construct' in this case?
BTW: class B in my project is something like a socket which need to do connect or do bind-like calls, so I want to put these expensive ops lazy.
Use pointer, preferably smart pointer.
class A
{
public:
void foo() {
if( pb == nullptr ) {
pb.reset(create_B_obj());
}
}
private:
B* create_B_obj(); //or return std::unique_ptr
private:
std::unique_ptr<B> pb;
int v;
};
You could avoid the dynamic allocation if you use placement-new instead, in which case you need custom deleter with std::unique_ptr:
class A
{
public:
void foo() {
if( pb == nullptr ) {
pb.reset(create_B_obj());
}
}
private:
B* create_B_obj()
{
return new (buffer) B( /* arguments */);
}
private:
std::unique_ptr<B, PlacementNewDeleter> pb;
alignas(B) char buffer[sizeof(B)]; //buffer used by placement new
int v;
};
where PlacementNewDeleter defined as:
struct PlacementNewDeleter
{
template<typename T>
void operator(T const *obj) const { obj->~T(); }
};
Hope that helps.
If you don't have access on the B class, then the easier way to do this is to use a pointer.
std::unique_ptr<B> b;
Then if your foo method:
B foo()
{
if (! b)
b.reset(new B(/* params */));
// or b.reset(create_B_obj());, which should return a pointer (may also return an unique_ptr)
return b;
}
The std::unique_ptr overloads operator bool and manages the memory so you don't have to delete.
Note: I changed the return type of the foo method as it seems more logical like this.

Dynamic Template Instantiation

I've got a class template, and I need to declare an object of that class, without defining the type parameters, so that I can define them conditionally later, e.g.:
template<typename T>
class A{
public:
A(T v){var = v};
~A(){};
T var;
}
int main(){
A<>* object; // Or sometihng along these lines...?
if(/* something*/)
object = new A<float>(0.2f);
else{
object = new A<int>(3);
}
}
Well, you certainly can't do that. You'll have to make A derive from another class, for example:
template<typename T>
class A : public B {
public:
A(T v){var = v};
~A(){};
T var;
}
int main(){
B* object;
if(/* something*/)
object = new A<float>(0.2f);
else{
object = new A<int>(3);
}
}
The easiest way to do this is to use another function.
template<typename T> void other_stuff(A<T>* object) {
// use T here
}
int main() {
if (condition)
other_stuff(new A<float>(0.2f));
else
other_stuff(new A<int>(3));
}
This maintains all type information and does not depend on inheritance. The disadvantage of inheritance is that T cannot appear in any function interfaces, but with this situation it can.
Templates are expanded at compile-time, so your problem is really just the same as the following:
struct A_float { // struct is easier when everything's public
A(float v) : var(v) {} // (use the ctor-initializer please!)
~A() {}
float var;
}; // don't forget the semicolon
struct A_int {
A(int v) : var(v) {}
~A() {}
int var;
};
int main() {
WhatType* object; // What type here?
if (/* something*/)
object = new A_float(0.2f);
else
object = new A_int(3);
}
Hopefully if you saw the above code, you'd think (as well as "maybe I should be using templates") "I am going to need a common base class for this, or else I'll refactor".
When you generate the two types at compile-time using a class template, this conclusion is the same.
I'd recommend the refactoring, going for a solution like Puppy's; creating an inheritance hierarchy just to work around a program logic flow flaw is programming backwards!
You can use void pointer while create object of class ALook at Following code sample :
template<typename T>
class A
{
public:
A(T v){var = v;};
A(){};
~A(){};
T var;
};
int main(){
A<void *> object;
if(1){ // do this
object = new A<float>(0.31f);
// type cast void pointer to get value
cout<<*(float*)object.var;
}
else{ // else do this
object = new A<int>(34);
// type cast void pointer to get value
cout<<*(int*)object.var;
}
}