Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I have header file as something like following.
class A;
class B;
class C;
Class a {
A *a;
B *b;
C *c;
};
Now, Class a does not using all A, B, C and around 40 others. I have around 40 forward declarations... Is possible to optimize it someone.. So, I can declared pointer to class on need bases instead of wasting memory for all pointer to all 40 odd class?
You can use union with type code or boost::variant
I would recommend for now that you should make a parent class and put as children all of the A,B,C,etc... Then in class use a list of the parent class, and put whatever subclass you need on it. But having this problem is actually due to wrong object oriented design. Learn the principles of OO design of a system in Java for example and then put them in use in C++.
Admitting you cannot rework your classes, and admitting you are using only one at time, you can use a union plus an ID or a "dynamically typed void*":
unsigned gen_id()
{ static unsigned id=0; ++id; return id; }
template<class T>
unsigned id_of()
{ static id = gen_id(); return id; }
class a
{
void* m;
unsigned type;
public:
template<class T>
a(T* p) :m(p), type(id_of<T>())
{}
template<class T>
T* get() const
{ return (id_of<T>()==type)? static_cast<T*>(m): nullptr; }
};
You can access a data as
A* pa = my_a.get();
if(pa) { /* what has to be done with A */ }
If you need more than one, consider a class b holding a vector of a.
For a more "standardized" implementation you can look at boost::any
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
I have 2 classes:
#include <iostream>
using namespace std;
class A
{
public:
virtual void print()=0;
};
class B: public A
{
public:
void print()
{
cout<<"B\n";
}
void printNew()
{
cout<<"Print new";
}
};
int main()
{
B b;
A *a=new B;
a->printNew();
delete a;
}
The compiler posts an error. If I want to use printNew through A, how can I do it? I thought it must include this feature because this proves useful in various situations.
Having a subclass instance B in a superclass A pointer is called Polymorphism in OOP.
From this A-type pointer, you would not be able to see the member function which exists only in B-type, clearly.
You could use this object as a B-type object by downcasting it though:
B *B = dynamic_cast<B*>(a);
As a has a dynamic type of B*, the cast is safe so a B pointer is returned.
Polymorphism doesn't work like that.
Although a has a dynamic type B*, its static type is A* and as such the pointer to member operator -> cannot reach the printNew function.
Crudely, you could write
virtual void printNew() { cout << "printNew() not implemented";}
in class A.
From C++20 it might indeed be possible to do as you want using reflection, with albeit different calling syntax.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
Say I have a class A with some member attributes. A also has a vector with objects of class B (std::vector<B>). Those B objects need some (let's say 5) of the attributes of A. I see two ways of handling this:
1) Let B have references to those attributes, and assign them in B's constructor.
2) Let B only have a reference to the A object, and get the attributes via public getAttributeXYZ() functions.
I can see that solution 1) technically knows less about A, therefore it's better because it couldn't for example call some wrong A function. But I feel like 2) is much cleaner, since the constructor is way smaller and the B class has much fewer (reference-) attributes itself. Is there a general better way or does it depend on the details?
Context: In my program, those members of A are classes for texture management, text drawing etc that can be shared by all of the B objects.
In this case, you can have your cake and eat it too, by giving the Bs access to only the relevant subset of A. There are multiple ways you could go about this.
One, gather the attributes in a dedicated class:
struct A
{
struct SharedData
{
int data;
// ...
};
A();
private:
SharedData sharedData;
std::vector<B> bs;
// other data here
};
struct B
{
B(A::SharedData *data) : data{data} {}
private:
A::SharedData *data;
};
A::A() : bs{B{&sharedData}} {}
Two, give A a dedicated interface to access these attributes:
struct SharedDataInterface
{
virtual int getData() const = 0;
};
struct A : SharedDataInterface
{
int getData() override { return sharedData; }
A();
private:
std::vector<B> bs;
int sharedData;
// other data here
};
struct B
{
B(SharedDataInterface *data) : data{data} {}
private:
SharedDataInterface *data;
};
A::A() : bs{B{this}} {}
I'm sure other variations on this topic are also possible.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I realize this is probably impossible but I will ask any ways.
Suppose I have a class:
class A{
int* array;
public:
//To be clear this class has other members
constexpr int GetSize() { return 10; /*actually this could be a little more than this*/ }
A(int arr[GetSize()]) : array(arr) { }
};
I should declare it like this:
int array[A::GetSize()] = { 0 };
A var(array);
But I am lazy and want it to be treated as if i did not declare the array at all...like this:
A var;
Is there any way to accomplish this?
Some constraints:
No dynamic memory allocation (this is for a micro controller)
I do not know the actual size of the array until I compile
The magic array number is derived from the sizeof(A) so I cannot include an array in the class because the sizeof(A) cannot be determined until after the array size is determined (which needs to know the sizeof(A))
The A class has to be able to be put into templates and initialized that way (this is the main constraint) example:
template <class T>
class Other{
public:
T foo(){
T a;
return a;
}
};
//Later
Other<A> other;
other.foo(); //This must compile
It sounds a lot like you want (at least an equivalent of) something like:
using A = std::array<int, size>;
A var;
This definitely fits your first two constraints. I can't quite figure out what your third constraint is intended to mean. You can certainly put a object of type array into a template, but it's not clear what you're talking about when you say: "and initialized that way". This can be initialized like a normal array, so A var = {0}; will be fine, if that's what you mean.
Note that although std::array was added in C++11, a reasonable analog of it can be written using only C++98 features (e.g., TR1 includes an array type that's essentially similar and compatible with C++98/03 compilers).
class B
{
friend class A;
int a, b, c; //Whatever you want here
};
class A : public B
{
int array[(sizeof B)];
public:
static constexpr int length = (sizeof B) + (sizeof int) * (sizeof B);
};
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I am trying to design an abstract class in C++. It is called AbstractCurve and it has
AbstractPoint's on it that are made up of x and y coordinates which are AbstractFieldElements.
I want to inherit from this to make, for example, a PrimeCurve that has PrimePoints and
PrimeFieldElements.
If I do something like this:
class AbstractPoint {
private:
AbstractFieldElement* x_;
AbstractFieldElement* y_;
};
How will I tell the compiler to make x_ and y_ be PrimeFieldElements when I create
the PrimePoint class?
Also, is there some better way to do this that I am missing?
Assuming the only difference between the classes is these datatypes, I would do something like this:
template <typename ElementType>
class Point {
private:
ElementType* x_;
ElementType* y_;
};
using AbstractPoint = Point<AbstractFieldElement>;
using PrimePoint = Point<PrimeFieldElement>;
If we take this to the next level up, we can keep going
template <typename ElementType>
class Curve {
private:
using Point = Point<ElementType>;
std::vector<Point> points_;
};
using AbstractCurve = Curve<AbstractFieldElement>;
using PrimeFieldCure = Curve<PrimeFieldElement>;
It is reasonable to use inheritance as you are suggesting to provide common behavior to a variety of curve/point types, but if the different types will use different internal data types, then templates are the way to go.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I'm trying to improve my generic architecture, and I've decided that a system that uses this type of ambiguous context referencing would be ideal for my purposes. However, I'm having trouble figuring out how to get the syntax to work. I don't even know if something like this is possible! I have slightly shiestier alternatives that accomplish mostly the same thing but this would be best:
class IContained
{
public:
virtual int getInt() = 0;
};
typedef std::shared_ptr<IContained>IContainedPtr;
template<template<class RefType, RefType& itsRef> class ContainedType>
class TestClass
{
TestClass() :
myContained(new ContainedType < TestClass, *this>())
{
}
int getContextInt()
{
return 3;
}
IContainedPtr myContained;
};
template<class RefType, RefType& itsRef>
class Contained:
virtual public IContained
{
int getInt()
{
return itsRef.getContextInt();
}
};
TEST(POTATO, PARTY)
{
TestClass<Contained> myTest();
int thing = myTest.myContained->getInt();
EXPECT_EQ(thing, 3);
}
I am not sure what do you want to implement but I can explain why you are not able to use
*this
as template argument. Templates provide you with compile-time polymorphism. It means that all templates arguments should be known at compile time.
this
is a class instance variable, is an address of class instance, so it could not be determined during compilation. The same as
*this