Hi, I've been programming a lot of c code,
and now I'm trying to set my mind into the c++ way of doing things.
so I'm trying to avoid pointers, and use refs instead.
As far as I understand pointers are to be avoided using stl's for instance.


I have 2 matrix classes that I want to contain in another class.
But at runtime I only want one of the matrixobjects allocated and instantiated.

In good old c, I would have made a pointer to the object,
and then only allocated the one I wanted.

But It seems that you need to instantiate everything in a class.

Or am I trying to do this in a odd way?

I think the problem is in class "aCollector" at line 20-27

#include <iostream>

class aClass{
 public:
  float f1;
  float f2;
  int *array;
  aClass(float var1, float var2){printf("norm class construct\n");f1=var1;f2=var2;}
};

template <typename T>
class aTemplate{
  float f1;
  float f2;
  T *array;
  aTemplate(float var1, float var2){printf("template class constructor\n");f1=var1;f2=var2;}
};


class aCollector {
public:
  int a;
  int b;
  aCollector(int chooseType,int f, int g): (chooseType==0)?myTemplate(f,g):myobj(fg){}
  aTemplate<int> myTemplate;
  aClass myobj;
};

int myFun(aStruct as){
  return 0;
}

int main(){
  aCollector acol(2,3);
  return 0;
}

thanks in advance

Dani AI

Generated

Short answer: store "one-of-two" with either a type-safe union (no heap), a smart pointer to a common interface (polymorphism), or an in-place buffer + placement-new (low-level). That avoids having both concrete members constructed when the collector is created.

Example using std::variant (no heap; choose one value at runtime):

#include <variant>

struct DenseMatrix { DenseMatrix(int r,int c); /*...*/ };
struct SparseMatrix { SparseMatrix(int r,int c); /*...*/ };

class Collector {
  std::variant<DenseMatrix, SparseMatrix> mat;
public:
  Collector(bool wantDense, int r, int c) {
    if (wantDense) mat.emplace<DenseMatrix>(r,c);
    else            mat.emplace<SparseMatrix>(r,c);
  }
};

Use std::visit or std::get_if to operate on the held type. This is ideal when the set of types is fixed and you want value semantics.

Example using runtime polymorphism and smart pointers (heap allocated, single virtual interface):

#include <memory>

struct IMatrix { virtual ~IMatrix() = default; virtual void compute() = 0; };
struct Dense : IMatrix { Dense(int,int); void compute() override; };
struct Sparse : IMatrix { Sparse(int,int); void compute() override; };

class Collector {
  std::unique_ptr<IMatrix> mat;
public:
  Collector(bool wantDense, int r, int c) {
    if (wantDense) mat = std::make_unique<Dense>(r,c);
    else           mat = std::make_unique<Sparse>(r,c);
  }
};

Smart pointers are idiomatic C++ and avoid manual delete; remember a virtual destructor on the base.

If you need maximum control (no heap, small footprint, but manual lifetime), consider an aligned storage buffer + placement-new and explicit destructor calls — only for advanced, performance-sensitive cases.

This expands on 's question and complements and : smart pointers and std::variant are the cleaner, safer approaches in modern C++. See std::variant, std::unique_ptr, and placement new notes at for details and pitfalls.

Recommended Answers

All 3 Replies

What's wrong with doing the following:

class aCollector {
public:
  int a;
  int b;
  aTemplate<int> myTemplate;
  aClass myobj;

  aCollector(int chooseType,int f, int g){
      if(chooseType==0)
         myTemplate = aTemplate<int>(f,g);
      else
         myobj = aClass(fg);
      }
};

For the above to work, you will need aClass::aClass() and aTemplate::aTemplate() defined.

Thanks, I thought it was possible to avoid instantiation,
untill runtime, and then choose.
But I'll define my aClass and aTemplate with a pointer then.

thanks again.

1. the c++ way of doing things != trying to avoid pointers, and use refs instead It's Java and C# ways of doing things ;).
2. Another common approach to defer an object initialization: add init member function to your class. Declare empty objects then allocate memory with init function call at a proper moment.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.