class A{
public:
A(): b(), c(), d(){}
private:
B b;
C c;
D d;
};
I have something similar to above code. where the initialization list is longer than here. Somewhere things go wrong in the initialization of objects. I want to find out where did it go wrong; after what object and in the initialization of which object did it fail.
I dont want to do it adding print statements to the respective classes.
One way I thought of having a class temp which will print a line for me in its constructor; This way I need to have as many objects as the number of class variables in my class A. There is no segfault or any exception being thrown which I can catch.
So is there any other way I can debug this other than having a class temp with as many objects of temp as the member variables. Is there smart way to debug this. Thanks.
#include <exception>
#include <string>
#include <typeinfo>
#include <iostream>
struct B
{
};
struct C
{
};
struct D
{
};
struct YourExceptionType:std::exception
{ std::string m_s;
YourExceptionType(const std::string &_r)
:m_s(_r)
{
}
~YourExceptionType(void) throw()
{
}
const char *what(void) const throw()
{ return m_s.c_str();
}
};
struct Show
{ Show(const char *const _p)
{ std::cout << _p << std::endl;
}
};
template<typename A>
struct ShowMe:Show, A
{ ShowMe(void)
try:Show(typeid(A).name()),
A()
{
} catch (const std::exception &_r)
{ throw YourExceptionType(
(std::string("Failed constructor of type ")
+ typeid(A).name()
+ ":" + _r.what()).c_str());
}
};
class A{
public:
A(): b(), c(), d(){}
private:
ShowMe<B> b;
ShowMe<C> c;
ShowMe<D> d;
};
Related
My code looks something like this:
class A {
...
};
template<typename T>
class B: public A {
...
};
A* pointerA = new B<X>(...);
But now I want to cast another pointerB to pointerA:
B<...>* pointerB = (B<...>*)pointerA;
How do I know what to insert into <...> or how I should do this correctly?
You can try the cast with dynamic_cast. If you dynamic_cast to a pointer type and it fails, you get a null pointer back. If you dynamic_cast to a reference type and it fails, you'll get an exception.
Example:
#include <iostream>
class A {
public:
virtual ~A() = default;
};
template<typename T>
class B : public A {};
int main() {
A* pointerA = new B<int>;
auto pointerB = dynamic_cast<B<double>*>(pointerA);
if(pointerB) {
std::cout << "cast succeeded\n";
} else {
std::cout << "cast failed\n"; // will print "cast failed"
}
delete pointerA;
}
If you have many of them stored in a vector you need to test all possible types to be able to cast back to the original type.
Example:
#include <iostream>
#include <memory>
#include <string>
#include <vector>
class A {
public:
virtual ~A() = default;
};
template<typename T>
class B : public A {};
int main() {
std::vector<std::unique_ptr<A>> vec;
vec.emplace_back(new B<int>);
vec.emplace_back(new B<std::string>);
for(auto& ptr : vec) {
if(auto b = dynamic_cast<B<int>*>(ptr.get())) {
std::cout << "B<int>\n";
} else if(auto b = dynamic_cast<B<std::string>*>(ptr.get())) {
std::cout << "B<std::string>\n";
} else {
std::cout << "Oh, unknown derived type stored ...\n";
}
}
}
It's preferable to add virtual methods to the base class and implement them in the derived classes to not have to do this cast at all though.
Defining the classes A with private constructor and destructor (it should be so!) and B as a friend class, how can I creat a vector of A objects in B and fill it with the function addA(). I got the error "error C2248: "A::~A": No access to private members whose declaration was made in the A class".
class A
{
private:
A();
A(const std::string& name, const float& num);
~A();
public:
friend class B;
private:
std::string name_;
float num_;
};
A::A()
{
name_ = "NoName";
num_ = 0.0;
}
A::A(const std::string& name, const float& num)
{
name_ = name;
num_ = num;
}
A::~A()
{
}
class B
{
public:
B();
~B();
void addA(const std::string name, const float num);
private:
vector<A> vecA;
};
B::B()
{
}
B::~B()
{
}
void B::addA(const std::string name, const float num)
{
A a(name, num);
vecA.push_back(a);
}
int main()
{
B b;
b.addA("Name", 1.0);
return 0;
}
While #Fureeish has a neat solution, here's a slightly simpler alternative: just wrap it.
class AccessPrivate;
class PrivStuff
{
private:
PrivStuff() {}
~PrivStuff() {}
public:
friend class AccessPrivate;
std::string m_data{};
};
class AccessPrivate
{
public:
AccessPrivate() = default;
~AccessPrivate() = default;
PrivStuff m_priv;
};
int main(int argc, char* argv[])
{
std::vector<AccessPrivate> myvec;
myvec.resize(4);
for (auto& stuff : myvec)
{
stuff.m_priv.m_data = "heya";
}
}
If you need something more complicated, like passing in arguments, just add an equivalent constructor to AccessPrivate and there you go. You can essentially treat AccessPrivate almost like the actual private class, just one level of indirection.
how can I create a vector of A objects in B [...] ?
You can't do that. While B is a friend of A, std::vector is not a friend of A, which means that it cannot access private members of A, e.g., constructor, which is required for a vector to work.
However, if you are okay with a little indirection, little potential performance hit and a change in your signature, you can replace the not-working std::vector<A> with a workig std::vector<std::unique_ptr<A, deleter>>.
It's important to note that plain std::unique_ptr will not work here. It has a similar problem to std::vector - it cannot access private destructor of A. One way to work around it is to outsource the job of constructing and destructing of As entirely to B - via explicit construction and destruction, that is:
new A(name, num)
static void deleter_a(A* a) { delete a; }
in B's scope.
Now we can do:
std::vector<std::unique_ptr<A, std::function<void(A*)>>> vecA;
instead of: std::vector<A> or std::vector<std::unique_ptr<A>>. This is important - neither std::unique_ptr nor std::vector construct or destruct your As. B is entirely responsible for constructing (new A(name, num)) and destructing (static void deleter_a(A* a) { delete a; }) As.
Full B class:
class B {
public:
B() {}; // or = default
~B() {}; // or = default
void addA(const std::string name, const float num);
private:
static void deleter_a(A* a) { delete a; }
using deleter_a_t = void(A*);
std::vector<std::unique_ptr<A, std::function<deleter_a_t>>> vecA;
};
void B::addA(const std::string name, const float num) {
vecA.push_back(std::unique_ptr<A, std::function<deleter_a_t>>{
new A(name, num), std::function<deleter_a_t>{deleter_a}
});
}
Contrary to what the other answers say, it is possible to do this without any extra indirection.
std::vector doesn't directly call the constructor and the destructor, but uses an allocator. If you want an std::vector to manage A objects, you just need to provide it an allocator that implements the construct and destroy functions, and that is either a friend of A or a nested class of B (since B is already a friend of A).
Example:
#include <memory>
#include <utility>
#include <vector>
class A {
A() = default;
~A() = default;
friend class B;
};
class B {
template<typename T>
struct custom_alloc : std::allocator<T> {
template<typename U, typename... Args>
void construct(U* p, Args&&... args){
::new(const_cast<void*>(static_cast<const volatile void*>(p))) U(std::forward<Args>(args)...);
}
template<typename U>
void destroy(U* p){
if constexpr (std::is_array_v<U>){
for(auto& elem : *p){
(destroy)(std::addressof(elem));
}
} else {
p->~U();
}
}
};
public:
std::vector<A,custom_alloc<A>> vec;
void new_A(){
vec.push_back(A());
}
};
For the implementation of construct and destroy, I used an equivalent implementation of the c++20 versions of std::destroy_at and std::construct_at. I suspect that destroy is overkill and just a call to the destructor would be sufficient, but I'm not sure.
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.
If I have two classes:
class A{
f();
}
class B{
f();
};
I need to assign one of these classes to an object based on a condition like:
define variable
if condition1
variable = A
else
variable = B
and then I would use the assigned variable.f();
You should look toward inheritance and virtual functions.
Code might look like
class Base
{
virtual void f() = 0;
};
class A : public Base
{
virtual void f()
{
//class A realization of f
}
};
class B : public Base
{
virtual void f()
{
//class B realization of f
}
};
And then you can do this
Base* VARIABLE = 0;
if (*condition*)
{
VARIABLE = new A();
}
else
{
VARIABLE = new B();
}
VARIABLE->f();
But it not always a good idea to use inheritance and virtual functions. Your classes A and B should have something in common, at least the meaning of function f().
Provided A and B are meant to be unrelated types (i.e. not part of an inheritance hierarchy), you could use Boost.Variant in combination with the boost::static_visitor<> class to achieve something similar:
#include <boost/variant.hpp>
#include <iostream>
struct A { void f() { std::cout << "A::f();" << std::endl; } };
struct B { void f() { std::cout << "B::f();" << std::endl; } };
struct f_caller : boost::static_visitor<void>
{
template<typename T>
void operator () (T& t)
{
t.f();
}
};
bool evaluate_condition()
{
// Just an example, some meaningful computation should go here...
return true;
}
int main()
{
boost::variant<A, B> v;
if (evaluate_condition())
{
A a;
v = a;
}
else
{
B b;
v = b;
}
f_caller fc;
v.apply_visitor(fc);
}
What you are doing is known in design patterns as the "Factory Pattern". The above answers cover how it should be implemented. You can get more information at How to implement the factory method pattern in C++ correctly and wiki (http://en.wikipedia.org/wiki/Factory_method_pattern).
Please see the example code below:
class A
{
private:
class B
{
public:
foobar();
};
public:
foo();
bar();
};
Within class A & B implementation:
A::foo()
{
//do something
}
A::bar()
{
//some code
foo();
//more code
}
A::B::foobar()
{
//some code
foo(); //<<compiler doesn't like this
}
The compiler flags the call to foo() within the method foobar(). Earlier, I had foo() as private member function of class A but changed to public assuming that B's function can't see it. Of course, it didn't help. I am trying to re-use the functionality provided by A's method. Why doesn't the compiler allow this function call? As I see it, they are part of same enclosing class (A). I thought the accessibility issue for nested class meebers for enclosing class in C++ standards was resolved.
How can I achieve what I am trying to do without re-writing the same method (foo()) for B, which keeping B nested within A?
I am using VC++ compiler ver-9 (Visual Studio 2008). Thank you for your help.
foo() is a non-static member function of A and you are trying to call it without an instance.
The nested class B is a seperate class that only has some access privileges and doesn't have any special knowledge about existing instances of A.
If B needs access to an A you have to give it a reference to it, e.g.:
class A {
class B {
A& parent_;
public:
B(A& parent) : parent_(parent) {}
void foobar() { parent_.foo(); }
};
B b_;
public:
A() : b_(*this) {}
};
This is an automagic, albeit possibly nonportable trick (worked on VC++ since 6.0 though). Class B has to be a member of class A for this to work.
#ifndef OUTERCLASS
#define OUTERCLASS(className, memberName) \
reinterpret_cast<className*>(reinterpret_cast<unsigned char*>(this) - offsetof(className, memberName))
#endif
class A
{
private:
class B
{
public:
void foobar() {
A* pA = OUTERCLASS(A, m_classB);
pA->foo();
}
} m_classB;
public:
foo();
bar();
};
Basically what Georg Fritzsche said
#include <iostream>
#include <cstring>
using namespace std;
class A
{
private:
class B
{
A& parent_;
public:
//B(); //uncommenting gives error
~B();
B(A& parent) : parent_(parent) {}
void foobar()
{
parent_.foo();
cout << "A::B::foo()" <<endl;
}
const std::string& foobarstring(const std::string& test) const
{
parent_.foostring(test); cout << "A::B::foostring()" <<endl;
}
};
public:
void foo();
void bar();
const std::string& foostring(const std::string& test) const;
A();
~A(){};
B b_;
};
//A::B::B() {}; //uncommenting gives error
A::B::~B(){};
A::A():b_(*this) {}
void A::foo()
{
cout << "A::foo()" <<endl;
}
const std::string& A::foostring(const std::string& test) const
{
cout << test <<endl;
return test;
}
void A::bar()
{
//some code
cout << "A::bar()" <<endl;
foo();
//more code
}
int main(int argc, char* argv[])
{
A a;
a.b_.foobar();
a.b_.foobarstring("hello");
return 0;
}
If you uncomment the default B constructor you would get an error
If you want to reuse functionality from A then you should inherit from A not nest B inside it.
Combining Igor Zevaka's and enthusiasticgeek's answers. Also, using reinterpret_cast for calculating offset (If you create class member variable using new keyword):
#include <iostream>
#include <cstring>
using namespace std;
template < typename T, typename U > constexpr size_t offsetOf(U T:: *member)
{
return (char*) &((T*) nullptr->*member) - (char*) nullptr;
}
class A
{
private:
class B
{
public:
B(string message);
~B();
void foobar()
{
A *pA = reinterpret_cast<A*> (reinterpret_cast< unsigned char*> (this) - offsetOf(&A::b_));
pA->foo();
pA->bar();
std::cout << "DONE!";
}
};
public:
void foo();
void bar();
A();
~A() {};
B* b_ = new B("Hello World!");
};
A::A()
{
cout << "A constructor\n";
};
A::B::B(string message) {
cout << "B constructor\n";
cout << "Message = " << message << "\n";
};
A::B::~B() {};
void A::foo()
{
cout << "A::foo()" << endl;
}
void A::bar()
{
cout << "A::bar()" << endl;
foo();
}
int main(int argc, char *argv[])
{
A* a = new A();
a->b_->foobar();
return 0;
}
Output:
B constructor
Message = Hello World!
A constructor
A::foo()
A::bar()
A::foo()
DONE!
References:
https://stackoverflow.com/a/10607424/9524565
https://stackoverflow.com/a/3058382/9524565
https://stackoverflow.com/a/20141143/9524565