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);
};
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 7 years ago.
Improve this question
I have 2 objects in my C++ program, both extending from the same parent class:
class A, and class B, both extending class base.
Is it possible create an object using class A, and then change it later in the program to class B?
Short answer, no. You cannot safely cast from A to B or B to A. You can safely cast to the base class since A IS_A base class and B IS_A base class but A and not a B and vice versa. There is no portable or safe way to do this. Whilst your compiler might let you do it and whilst it might appear to work the result of casting between to unrelated classes in this manner is undefined.
Incidentally, there is no reason why you can't add a cast constructor to allow A to be constructed from B and vice versa. That would be perfectly safe. You would just use the members of A to initialise the members of B and vice versa. Any members that are not common you'd have to deal with, probably be assigning them default values.
The following code works:
#include <iostream>
class Base {};
struct A : public Base {int a;};
struct B : public Base {int b;};
int main()
{
A *a = new A();
a->a = 1;
B *b = reinterpret_cast<B *>(a);
std::cout << b->b << std::endl;
return 0;
}
This is extremely ugly though and won't work properly if A and B don't have the exact same memory layout. This works if you need a and b to be the same object. If you don't mind them being different objects and residing in different places in memory then you can just write a constructor in B that receives an object of type A or a conversion operator.
This sounds like a classic example of the XY Problem and there probably exists a much more elegant solution to your actual problem.
As others have mentioned, no you cannot do this...technically. You can in fact achieve this effect through convert constructors and virtual functions.
If you write a convert constructor from A to B and B to A:
A::A(B convertFrom); // Convert from B to A
B::B(A convertFrom); // Convert from A to B
And you make the essential parts of each class virtual:
class base
{
virutal void baseClassFunction();
};
class A
{
virtual void baseClassFunction()
{
// Do things for A
}
};
Class B
{
virtual void baseClassFunction()
{
// Do things for B
}
}
Then you can simply make a pointer of type base which can hold a reference to either A or B.
Example bringing it all together;
int main()
{
base *ptr = new A();
bool needs_to_be_B;
...
// Program logic
ptr->baseClassFunction();
...
if(needs_to_be_B)
{
base *tmp = new B(*ptr);
delete ptr;
ptr = tmp;
delete tmp;
}
// ptr is now a B
ptr->baseClassFunction();
}
If you are confused look up virtual functions and convert constructors.
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 9 years ago.
Improve this question
template <class T>
Vector<T>::Vector() : _size_(0){
this->_capacity_ = 10;
buffer = new T[this->_capacity_];
}
template <class T>
Vector<T>::Vector(unsigned int s) {
this->_size_ = s;
this->_capacity_ = _size_;
this->buffer = new T[this->_capacity_];
init(0, this->_size_);
}
template <class T>
Vector<T>::Vector(unsigned int s, const T &initial){
this->_size_ = s;
this->_capacity_ = s;
this->buffer = new T[this->_capacity_];
init(0, s, initial);
}
My code uses the this keyword a lot. Is it considered good practice to call member functions within a class rather than just access it directly, without the this keyword? If I always call member functions to access member variables, would it incur overhead? What do the C++ implementations do?
There is no overhead because the code is compiled. When you do:
this->_size = 5;
and
_size=5
The compiler treats them as identical and produces identical code.
If you like using 'this' then use it.
Personally I don't like it.
The way you initialize members in your constructors is wrong. You should use initializer lists:
struct X {
X() : a(1), b(2), c(3) {}
int a, b, c;
};
otherwise the value will have to be default initialized and reset afterwards.
The cost of accessing non-virtual member functions is hard to calculate because it depends on inlining. If it is inlined, it is overhead free. This is very likely for simple get/setters.
For virtual member functions it depends on the capability of the compiler to possibly hoist the virtual call at compile time, but you should assume that there will be overhead.
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