Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

Crispy

constructor

This topic is 5984 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

hi, Here's my problem:

class A
{
  public:
    A(A*);
};


class B : public A
{
  public:
    B(A* a) : A(a) {}
};


class C : public B
{
  private:
    std::vector<B*>b_vec;

  public:
    C() : B() {}
   
    void AddA(A* a)
      {
      B* b = new B(a);
      b_vec.push_back(b);
      }
};
   
How do I write the constructor code for A::A(A* a)? My BC5.02 gives me a "cannot assign to 'this'" error if I write: A::A(A* a) { this = a; } and suggests something like this = malloc(n). This is something I can't understand. I mean, if I write this = (A)malloc(sizeof(*a)); or something it gives me an error explaining that there's no A::A(void*) constructor defined, which is true. What would the correct syntax in this case be like? Thanks in advance, Crispy edit: darn html.... [edited by - crispy on May 30, 2002 5:33:09 PM]

Share this post


Link to post
Share on other sites
Advertisement
Why do you want to do this? It seems very dubious. To initialise an object from a pointer to the same type of object seems very odd. And initialising a child class from a pointer to a base class seems even worse. And trying to initialise that second child class by calling a default constructor in its parent that simply doesn't exist is just plain wrong. So I think your thinking is out somewhere along the line.

If you're trying to write a copy constructor, the general way is this:

A::A(const A& rhs) // rhs stands for Right Hand Side - call it what you like
{
// assign individual members here
}

You can't say 'this = whatever' as you can't legitimately change the 'this' pointer. You could perhaps use '*this = whatever' if you wanted to implement the copy constructor in terms of the assignment operator.

[ MSVC Fixes | STL | SDL | Game AI | Sockets | C++ Faq Lite | Boost | Asking Questions | Organising code files ]

[edited by - Kylotan on May 30, 2002 8:21:37 PM]

Share this post


Link to post
Share on other sites
In addition, I believe this is constant. Someone please correct me on this if I''m wrong.

/*=========================================*/
/* Chem0sh */
/* Lead Software Engineer & Tech Support */
/* http://www.eFaces.biz */
/*=========================================*/

Share this post


Link to post
Share on other sites
If you are trying to assign to the this pointer, there is something wrong with your design. Simple as that. As Chem0sh points out, C++ enforces this by making this a constant pointer.

Share this post


Link to post
Share on other sites
Okay, a little more in-depth explanation:

When I call C::AddA(), I pass in a structure/class of A (let''s call it ca). When I create the B in C::AddA(), I pass it the ca. Since A is already a member of B by default because of the class declaration ''class B : public A'', B already contains all of the data members of class A. So I need to assign the data contained in ca to these data members of A from which B is derived.

Is there really no other (simpler) way than to copy all of the variables and data members one by one into B::A ? I mean, I''m stuck with a large class here with alot of data to copy - writing assginement code for each of them seems like an awful waste of space. So what I was figuring was to pass a pointer of an already initialized class A (ac) to a constructor of A when B is constructed and point the newly created a to the already created A (ac). Obviously, this is not done (this way) and is, as Kylotan well put it ''just plain wrong''. I can see that, but I''m also confused here - what would the right solution be like?

Thanks,
Crispy

Share this post


Link to post
Share on other sites
quote:
Original post by Crispy
what would the right solution be like?

It''s not possible to say, since you don''t appear to modelling anything in particular. You can play around with language features all you like, but if you''re not solving a real-world problem, then there can be no "right way". So, what''s the real question?

Share this post


Link to post
Share on other sites

class TWaveForm
{
public:
TWaveForm(TWaveForm* wf)
{
//i need to assgn the data pointed to by wf to this
//instance of TWaveForm, so here''s the bottleneck
}

//data for the waveform and loads of other stuff related to it
};

class TSoundObject : public TWaveForm
{
public:
TSoundObject(TWaveForm* wf) : TWaveForm(wf) {}
//loads of stuff to wrap around TWaveForm
};

class TSoundManager : TSoundObject
{
private:
std::vector<TSoundObject*>sounds;

public:
TSoundManager() : TSoundObject {}

//make an easy way of adding a TWaveForm object to
//sounds without previously creating a new
//TSoundObject object
void AddSound(TWaveForm* wf)
{
TSoundObject* o = new TSoundObject(wf);
sounds.push_back(o);
}
//stuff to wrap around and bind together TSoundObject
};


I can''t make it any more clear than this - I even used the actual class names . Sorry if there are any typos.

Crispy

Share this post


Link to post
Share on other sites
Just a fast hack:


  
class TWaveForm
{
public:
/* REMOVED */
/*
TWaveForm(TWaveForm* wf)
{
//i need to assgn the data pointed to by wf to this
//instance of TWaveForm, so here''s the bottleneck
}
*/

//data for the waveform and loads of other stuff related to it
};

class TSoundObject /* REMOVED: : public TWaveForm */
{
private:
TWaveForm *_wf;
public:
TSoundObject(TWaveForm* wf) : _wf(wf) /*CHANGED :TWaveForm(wf)*/
{}
//loads of stuff to wrap around TWaveForm

};

class TSoundManager : TSoundObject
{
private:
std::vector<TSoundObject*>sounds;

public:
TSoundManager() : TSoundObject {}

//make an easy way of adding a TWaveForm object to

//[i]sounds[/i] without previously creating a new

//TSoundObject object

void AddSound(TWaveForm* wf)
{
TSoundObject* o = new TSoundObject(wf);
sounds.push_back(o);
}
//stuff to wrap around and bind together TSoundObject

};



Forever trusting who we are
And nothing else matters
- Metallica

Share this post


Link to post
Share on other sites
Right, that''s clearer. The first thing of note is that I don''t think you really want TSoundManager deriving from TSoundObject. The relationship is wrong. Secondly, if you want to store pointers to TSoundObjects in the vector, then why are you passing TWaveForm pointers into it? I suspect you really want to store pointers to TWaveForms and be done with. Lastly, you do know that a derived object''s base is initialised on construction? I''m not sure why you''ve got those weird constructors. Remember, a TSoundObject "IS-A" TWaveForm. You seem to be massively over-complicating things.

As an additional tip, I strongly recommend you use boost::shared_ptr rather than bare pointers. Check out Boost''s website.


[ C++ FAQ Lite | ACCU | Boost | Python | Agile Manifesto! ]

Share this post


Link to post
Share on other sites
Thanks SabreMan and Gabriel Fleseriu

Some stuff to explain, though:

1) I do want TSoundManager to be derived from TSoundObject because of a bunch of functions that would otherwise have to be rewritten (such as playback functions which make TSoundManager a wee bit more than a simple container for a set of sounds - I could use an array or a vector for that and not create a class at all. TSoundManager is like the song object into which all of the sounds have been mixed - it is basically a simple waveform consisting of sounds and dynamic stuff that I call events that describe the behaviour of these sounds over time).
2) It is essential that I keep TSoundObject objects in the vector because they contain a bunch of info that is not described by TWaveForm, such as some dsp stuff to create a sound based on the waveform; if the sound has a looping point, where it is, etc.
3) Massively overcomplicating is probably what I do most of the time when I don''t know the solution at the first glance. That''s what everybody does (I hope ) - so there you have it. I was simply trying to think of the most optimal way to preserve both memory consumption and code size.

Crispy

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!