0
struct StructA
{
    int i;
    int j;
};

// Method 1
struct StructBA
{
    int k;
    StructA sa;
}

// Method 2
struct StructCA
{
    int m;
    StructA *psa;
};

// Method 3
struct StructDA
{
    int n;
    boost::shared_ptr<StructA> psa;
};

Basically, I need to pass a structure which contains other structures as a function parameter to constructor of a class. what is the best design practice in this situation?

Note: please correct my understanding if it is incorrect.

My understanding for method 1> There is the simplest way to handle the data and we don't need to explicitly allocate resource and release resource. The only concern is that it may involve unnecessary copies. However, if I always use pass by reference, this should not be a problem.

My understanding for method 2> This method has been used extensively in FMOD library (http://www.fmod.org/), so it must have its edge. But we have to manually allocate and release resource.

My understanding for method 3> It removes the requirement for manually releasing the allocated resource but it involves overhead compared to method 2.

So which method should I use in practice and when?

q0987
  • 34,938
  • 69
  • 242
  • 387

3 Answers3

0

Why don't you just have the struct be a parameter of the constructor?

struct StructA //original struct
{
    int i;
    int j;
};

struct StructB
{
    StructB(StructA& ref){                 //Just struct
        std::cout<<"i: "<<ref.i<<", j:"<<ref.j<<"\n";
    }

    StructB(StructA& ref, int param){      //Struct and parameter
        std::cout<<"i: "<<ref.i<<", j: "<<ref.j<<", parameter: "<<param<<"\n";
    }
};
Skyler Saleh
  • 3,961
  • 1
  • 22
  • 35
0

Consider passing a const reference to the constructor (assuming it does not modify the original structure during construction).

StructB::StructB(const StructA &myobject)
{
     sa = myobject;
}

This will involve only one copy operation, which is during assignment (thereby avoiding copying during argument passing)

If you want to avoid copying altogether, then pointers is your answer. Simply pass the pointer as the argument (StructA *structure) - but then you have an issue of managing the allocated heap memory (gotta call new StructA and delete). Either use smart pointers to solve that, or manage memory manually - too many ways to do it :)

Let me know if you have questions!

Kaa
  • 677
  • 6
  • 17
0

If this is meant to only be a reference then you can use a reference member and instantiate it during the ctor.

StructB{
StructB(const StructA & myobj) : sa( &myobj ){}
StructA &sa;
};

I believe the sharedptr will try to destroy the object when StructB goes out of scope so this is probably a bad idea if you are planning on using the original instance after this object goes out of scope. And this should throw an exception especially if you have declared StructA on the stack and not heap. Your other option would be to make StructA a movable object that would then take ownership by way of assignment.

StructA{
StructA( StructA && toMove ){ *this = std::move( toMove ); };
StructA & opertor=( StructA && toMove ) { //swap this and toMove };
};

StructB{
StructB( StructA && toMove ) : sa( std::move( toMove ){};
};
jbreiding
  • 374
  • 2
  • 9