Hey guys i'll show the code first then explain my problem:

Class A
{
/*Variables required by A, B, C and D */
/*functions required by B and C*/
};
Class B
{
/*some of it's own functions and variables*/
};
Class C
{
/*some of it's own functions and variables*/
};
Class D
{
/*calls all the functions in A, B and C*/
};

So basically, I need the above and wondered what would be the best system design. I was thinking of using virtual functions with inheritance but then I come with the issue that if I make an object to access the class B, that same objects data will need to be used by the object I make for class C. Eg:

B bdata;
bdata.function();
C cdata;

/* add some function here to input all of the object bdata's data into cdata*/

cdata.function(); /* in order to get this function to work, it requires the data from bdata*/

So, my questions are:

1. What is the best system design and why? (I don't want to challenge you, i'd like to know the reason behind it to enhance my knowledge)
2. Is it possible to share object data between objects?

Also, please try not to get too technical, I have a bit of knowledge on C++ but it's not that great.

Thanks for your help!

Recommended Answers

All 18 Replies

Im just learning classes :( But by sharing object data I will assume u mean something like a global variable.. The value from a textbox can be shared throughout the entire program.. is that what u want/mean?

use diamond inherentence

class A
{
public:
    A() {x = 0;}

protected:
    int x;
/*Variables required by A, B, C and D */
/*functions required by B and C*/
};

class B : public A
{

};

class C : public A
{

};

class D : public B, public C
{

};

You're about the third person I've seen ask a question like this the last couple days. This must be some sort of exercise for a class.

What is the focus of your current chapter? The behavior you are seeking is certainly possible; odd, but possible.

You could do it through inheritance, but you'll probably run into the "dreaded diamond" or you could do it through "friend" classes, but that's not really a good practice.

EDIT:
Oops, AD snuck in there...

There are two fundamental ways to do this (at least what I can understand of it, I think a more concrete example would be better): Composition and Inheritance.

In the case you presented first (with A, B, C, and D), I think inheritance seems most appropriate (although the example is far to vague to really tell). You could do this:

class A
{
/*Variables required by A, B, C and D */
/*functions required by B and C*/
};
class B : public A
{
/*some of it's own functions and variables*/
};
class C : public B
{
/*some of it's own functions and variables*/
};
class D : public C
{
/*calls all the functions in A, B and C*/
};

With this, all the things you described inside the comment blocks should be easy to do.

**EDIT**
Or as AD posted, a diamond inheritance is another possibility:

class A
{
/*Variables required by A, B, C and D */
/*functions required by B and C*/
};
class B : virtual public A
{
/*some of it's own functions and variables*/
};
class C : virtual public A
{
/*some of it's own functions and variables*/
};
class D : public B, public C
{
/*calls all the functions in A, B and C*/
};

********

However, you have to realize that these design decisions are not and should not be driven by what you (think you) need, but by functionalities that your classes provide (their "contracts"). So, a discussion on "best system design" is futile without a clear definition of what functionalities are required (what you described is your preconceived idea of what you will need (as access to data and functions between classes) to accomplish a functionality that you have omitted to describe).

use diamond inherentence

class A
{
public:
    A() {x = 0;}

protected:
    int x;
/*Variables required by A, B, C and D */
/*functions required by B and C*/
};

class B : public A
{

};

class C : public A
{

};

class D : public B, public C
{

};

I think you forgot about virtual inheritance. It's needed to eliminate ambiguities inherrent to the structure so that the diamond works properly.

class A {
//...
};

class B : virtual public A {
//...
};

class C : virtual public A {
//...
};

class D : virtual public B, C {
//...
};

EDIT:
*sigh* Jumped again... :D

Please read through all of my post, it contains more than one question.

Just to answer some questions:

@Fbody: I don't know anyone else doing this, this is my own project at uni that only I am doing.

Ok, let me elaborate on what I was saying before. My project requires me to create a plugin in Sketchup whereby I get the user to enter some data, this data is sent sent to C++ via text files and is read into different functions depending on which text file it is.

The different classes I will use are component, slab, beam, column, foundation and building.

Component holds specific functions from the slab, beam, column and foundation classes which are the same and the rest of the functions are held by their specific classes.

The functions are generally made so that the designing of that specific part (beam, column, foundation or slab) is covered by all the functions in it's corresponding class.

The Building class "combines" the functions in the correct order for each component.

The text files sent from sketchup are split into main, slab, column, beam and foundation.

The classes of beam, slab, column and foundation all require the main.txt file and some classes require not only their own text file but some variables from other text files, eg: slab requires main.txt, slab.txt and 2 variables from beam.txt.

Here is an example of two building functions:

class Building
{
public:
   void combined_slab();
   void combined_beam();
};

void Building::combined_slab()
{
   slab sb;
   sb.function1();
   sb.function2();
   sb.function3();
}

void Building::combined_beam()
{
   beam bb;
   bb.function_a();
   bb.function_b();
   bb.function_c();
}

Therefore, I need the object bb to be able to access the data from object sb.

I might also like to point out, currently i'm using friend class for building with component so building can access some data from within component, and it is also inheriting from slab, beam, column and foundation. I tried to let it access component aswell but it says that is too ambiguous.


My problems summarised:

1. What type of system design should I use?
2. What should I do about the get_data() function (inputs the data from text files)
3. How do I get to share data across objects?
4. Can I create an array of objects determined on run-time?

Some solutions I had to my problems:

1. Inheritance (with multiple) or Polymorphism
2. Could use virtual functions but I don't know how to share data between class objects, I could use global functions but I heard that they're not recommended.
3. I could use accessor functions but then i'd be here for days just writing and rewriting code and also, it is possible that my code will need to create a certain amount of object of slab, beam, column and foundation, this will only be determined on run-time, therefore, it may not be able to write an accessor function as I will not know which object it can be accessed with.
4. I believe I have read about it somewhere but am not entirely sure, I am aware though that it would require a destructor as the data would be dynamic.


Hope you guys can help and thank you!

>>Please read through all of my post, it contains more than one question.
I'm aware that you asked more than one question, but they really stem from the same root question, "How do I get my Classes to interact accurately and efficiently".

My problems summarised:

1. What type of system design should I use?
2. What should I do about the get_data() function (inputs the data from text files)
3. How do I get to share data across objects?
4. Can I create an array of objects determined on run-time?

:-/ Hmmmm.... :-/

  1. You'll need a combination of designs to do this correctly:
    • The inheritance relationship models the x is a y relationship (i.e. a Beam is a Component). So, I can see Slab, Beam, and Column inheriting from Component; Foundation is a bit of a toss-up, it depends on how you intend to use it. But a Building really isn't a Component, it's a finished product containing a collection of Components, so I don't see it as a good candidate for inheritance (see below).
    • A Building has a Beam component; a Building has a Column Component; this situation is better modeled by composition. Based on that, I almost think you would want to use Polymorphism inside Building and have it contain a vector of Component*. This will give Building access to the public interface of every Component. The problem is that without some form of RTTI it will hide from the client code what specific type of component each individual one is.
  2. I think that depends on what you intend get_data() to do. Do you want each class to have its own get_data so that each object reads the appropriate file or do you want Building to have the only one and generate the rest of the objects? I can see where it would be beneficial to have it be part of Building. That would allow you to generate objects and push them onto the Components vector. A centralized get data would have a more complex logical structure than individual ones, but there would only be one method whereas individual functions would be simpler, but you would have more functions to maintain.
  3. Why exactly do you need Building to access the protected members of (for example) Beam? Does it need to calculate some sort of moment? If that's the case, I think you would be better off adding another function to Beam called something like CalculateMoment that would return the moment to Building for it to use.
  4. See my answer to 1.
commented: Helping me alot with my issue and trying to solve it, for that I am extremely grateful +1

Sorry, ran out of edit time...

Another option for get_data() would be to make it a global function independent of any class. It would then read all of the appropriate data and "Build" the Building by calling an AddComponent method that is part of the Building class.

That's great fbody, thanks for the help, i'll read up a bit on the part you mentioned about building, as i'm not entirely experienced in polymorphism or inheritance; I want to make sure it works in the most simplest of methods as well as the most effective and it sounds like what you're saying is true for both of them :)

Also, I want get_data() to read in the data each time a new object is called. Some variables are the same in beam and slab but they change for each case, therefore, instead of adding too many variables, i've just got the same variables but re-defined them so that when the object is made, they will hold the correct information.

I'll read a bit of background information around what you've said as i'm still a bit hazy as to how I will share the object's internal data, i presume one of the methods enables it in building but I may not know that yet :p

You can also create a composition of small POD classes (Plain Old Data) for the data that some components might have in common, instead of an awkward inheritance scheme.

As I understand it, slab and beam are really two different types of objects, but they share common type of data. For example, say they both have, as defining data members, x-y coordinates for the end-points, and maybe some material properties (stress-strain, yield point, Poisson ratio, Young's modulus, etc.) (assuming you are doing some sort of structural analysis). Then, inheriting one from the other or vice-versa is not really meaningful, but creating small classes that handle a small subset of the properties is much easier, and they can have all their data members public. For example:

struct LineSegment {
  double start_x, start_y;
  double end_x, end_y;
  void get_data(istream& in) {
    in >> start_x >> start_y >> end_x >> end_y;
  };
};

struct Material {
  double yield_stress;
  double E, mu;
  void get_data(istream& in) {
    in >> yield_stress >> E >> mu;
  };
};

class Slab : public Component {
  private:
    LineSegment geom; //has a "line-segment" geometry, but is rigid (not material)
    //... other data members...
  public:
    void get_data(istream& in) {
      geom.get_data(in);
      //get data for the other data members..
    };
};

class Beam : public Component {
  private:
    LineSegment geom; //has a "line-segment" geometry.
    Material mat;     //has a material that characterizes its deformability.
    //... other data members...
  public:
    void get_data(istream& in) {
      geom.get_data(in);
      mat.get_data(in);
      //get data for the other data members..
    };
};

That is composition. Since LineSegment and Material are really just simple classes that hold a set of data members, it is OK for them to have all those members public, thus, granting Slab and Beam and any other class full access to them. Using the above, the reusability is maximum, and coding effort is minimal.

>>i'm still a bit hazy as to how I will share the object's internal data,
As long as you declare the members of Component correctly (as protected instead of private), Beam, Slab, etc. will be able to access them. That's the whole point of the inheritance mechanism.

Your confusion is understandable, but you really haven't answered my question. What you are proposing is doable but not advisable. That's why I'm reluctant to answer that part of your question at the moment.
Why do you need Building to access the internals of Component/Beam/Slab/etc.? Based on the description of your scenario, I think I know what you have in mind; I'm trying to warn you that it's a design that is contrary to good OOP practice and suggest you consider other options first.

You're better off creating a common public interface for your Components that Building has to use. This public interface would be designed in such a way as to
make your Components responsible for performing their own calculations. Then, once they've calculated a value, they give the calculated value to Building to do whatever it wishes with that particular value.

This is an over-simplified example:

class Component {
 protected:
   double Modulus;

 public:
   double getMoment() = 0;
}; //end Component declaration


class Beam : public Component {
 protected:
   //members unique to a Beam

 public:
   double getMoment() {
     //calculate the moment
     return moment;
   }
}; //end Beam declaration


class Building {
 private:
   vector<Component*> myComponents;   //the Building's Components

 public:
   void Analyze() {
     //misc. code
     double compMoment = myComponents[i].getMoment();
     //additional operations
   }

   void AddComponent(Component *newComp) {
     myComponents.push_back(newComp);
   }
}; //end Building declaration


int main () {
  Building myBuilding;
  myBuilding.addComponent(new Beam);
  myBuilding.Analyze();
  //additional code
  return 0;
} //end main()

You can also create a composition of small POD classes (Plain Old Data) for the data that some components might have in common, instead of an awkward inheritance scheme.

As I understand it, slab and beam are really two different types of objects, but they share common type of data. For example, say they both have, as defining data members, x-y coordinates for the end-points, and maybe some material properties (stress-strain, yield point, Poisson ratio, Young's modulus, etc.) (assuming you are doing some sort of structural analysis). Then, inheriting one from the other or vice-versa is not really meaningful, but creating small classes that handle a small subset of the properties is much easier, and they can have all their data members public. For example:

struct LineSegment {
  double start_x, start_y;
  double end_x, end_y;
  void get_data(istream& in) {
    in >> start_x >> start_y >> end_x >> end_y;
  };
};

struct Material {
  double yield_stress;
  double E, mu;
  void get_data(istream& in) {
    in >> yield_stress >> E >> mu;
  };
};

class Slab : public Component {
  private:
    LineSegment geom; //has a "line-segment" geometry, but is rigid (not material)
    //... other data members...
  public:
    void get_data(istream& in) {
      geom.get_data(in);
      //get data for the other data members..
    };
};

class Beam : public Component {
  private:
    LineSegment geom; //has a "line-segment" geometry.
    Material mat;     //has a material that characterizes its deformability.
    //... other data members...
  public:
    void get_data(istream& in) {
      geom.get_data(in);
      mat.get_data(in);
      //get data for the other data members..
    };
};

That is composition. Since LineSegment and Material are really just simple classes that hold a set of data members, it is OK for them to have all those members public, thus, granting Slab and Beam and any other class full access to them. Using the above, the reusability is maximum, and coding effort is minimal.

They share same data as well as the same functions in certain cases, does that mean inheritance will be more beneficial?

You can also create a composition of small POD classes (Plain Old Data) for the data that some components might have in common, instead of an awkward inheritance scheme.

As I understand it, slab and beam are really two different types of objects, but they share common type of data. For example, say they both have, as defining data members, x-y coordinates for the end-points, and maybe some material properties (stress-strain, yield point, Poisson ratio, Young's modulus, etc.) (assuming you are doing some sort of structural analysis). Then, inheriting one from the other or vice-versa is not really meaningful, but creating small classes that handle a small subset of the properties is much easier, and they can have all their data members public. For example:

struct LineSegment {
  double start_x, start_y;
  double end_x, end_y;
  void get_data(istream& in) {
    in >> start_x >> start_y >> end_x >> end_y;
  };
};

struct Material {
  double yield_stress;
  double E, mu;
  void get_data(istream& in) {
    in >> yield_stress >> E >> mu;
  };
};

class Slab : public Component {
  private:
    LineSegment geom; //has a "line-segment" geometry, but is rigid (not material)
    //... other data members...
  public:
    void get_data(istream& in) {
      geom.get_data(in);
      //get data for the other data members..
    };
};

class Beam : public Component {
  private:
    LineSegment geom; //has a "line-segment" geometry.
    Material mat;     //has a material that characterizes its deformability.
    //... other data members...
  public:
    void get_data(istream& in) {
      geom.get_data(in);
      mat.get_data(in);
      //get data for the other data members..
    };
};

That is composition. Since LineSegment and Material are really just simple classes that hold a set of data members, it is OK for them to have all those members public, thus, granting Slab and Beam and any other class full access to them. Using the above, the reusability is maximum, and coding effort is minimal.

While this is true, and probably a better solution for the Components aspect of the problem, it doesn't solve the OPs main problem.

As I understand the problem presented, the main problem is that the OP wants Building, which should be external to, and composed of Beams and Slabs to have free access to the internal members of Beam, Slab, etc. which is neither a safe, nor realistic, design. A building couldn't care less about the specifics of a Component, all that it cares about is that the component exists and that it works for it's intended purpose. If the component doesn't work, the Building fails.

>>They share same data as well as the same functions in certain cases,
What exactly do you mean by "They share same data..."? Are you trying to say that, for example, every Beam should have a variable with a common value? This is completely different from what you were saying earlier. If that's the case, you'll want to consider a "static" member. When you declare a member "static" only one copy of the variable exists and every instance of the class/struct accesses the same value.

>>i'm still a bit hazy as to how I will share the object's internal data,
As long as you declare the members of Component correctly (as protected instead of private), Beam, Slab, etc. will be able to access them. That's the whole point of the inheritance mechanism.

Your confusion is understandable, but you really haven't answered my question. What you are proposing is doable but not advisable. That's why I'm reluctant to answer that part of your question at the moment.
Why do you need Building to access the internals of Component/Beam/Slab/etc.? Based on the description of your scenario, I think I know what you have in mind; I'm trying to warn you that it's a design that is contrary to good OOP practice and suggest you consider other options first.

You're better off creating a common public interface for your Components that Building has to use. This public interface would be designed in such a way as to
make your Components responsible for performing their own calculations. Then, once they've calculated a value, they give the calculated value to Building to do whatever it wishes with that particular value.

This is an over-simplified example:

class Component {
 protected:
   double Modulus;

 public:
   double getMoment() = 0;
}; //end Component declaration


class Beam : public Component {
 protected:
   //members unique to a Beam

 public:
   double getMoment() {
     //calculate the moment
     return moment;
   }
}; //end Beam declaration


class Building {
 private:
   vector<Component*> myComponents;   //the Building's Components

 public:
   void Analyze() {
     //misc. code
     double compMoment = myComponents[i].getMoment();
     //additional operations
   }

   void AddComponent(Component *newComp) {
     myComponents.push_back(newComp);
   }
}; //end Building declaration


int main () {
  Building myBuilding;
  myBuilding.addComponent(new Beam);
  myBuilding.Analyze();
  //additional code
  return 0;
} //end main()

I think i'm mixing up my words, let me paste some of my current code here for building:

class building: public slab, beam, column, foundation //don't know if it will access component
{
private:
public: //calc all the typical components and then the final ones seperately providing them in two different output files each for sketchup
	void combined_slab_calcs();
	void combined_beam_calcs();
	void combined_column_calcs();
	void combined_foundation_calcs();
	
	//need to make functions here which create all the structural members: array?
};

void building::combined_slab_calcs()
{//keeping variables within the object reduces warnings, ambiguity and danger of creating errors in other calcs
	slab bs;
	bs.component::get_data();
	bs.get_data();
	cout << bs.fck; //my fck value (in the main file) is not being read into the object bs
	getch();


	bs.span = bs.sspan;
	bs.min_meas = bs.fslabthick;
	bs.link =0;


	bs.effdepth();

	bs.seffdf = bs.effdf;


	bs.loadmoment();
	bs.ULSsup();
	
	bs.r_su_n_o = bs.s_r_su_n_o, bs.r_su_a_o = bs.s_r_su_a_o, bs.r_su_n_t = bs.s_r_su_n_t, bs.r_su_a_t = bs.s_r_su_a_t;

	bs.ULSspan();

	bs.r_s_n_o = bs.s_r_s_n_o, bs.r_s_a_o = bs.s_r_s_a_o, bs.r_s_n_t = bs.s_r_s_n_t, bs.r_s_a_t = bs.s_r_s_a_t;

	bs.shearresist();
	bs.SLScheck();
}

void building::combined_beam_calcs()
{
}


int main()
{
	building build;
	build.combined_slab_calcs();
	return 0;
}

My problem is I want the object bs to obtain the main data file, i'm trying to call. Also, later when i make a combined_beam_calcs that will have an object of bb, i want the sspan in bs to = the sspan in bs. I don't want to have to write that manually, i was wondering if there was some function like "bb takes data from bs" or something like that? Am i making sense, if i'm just mumbling I can paste all the code here but i'm afraid it might be a bit long.

Also, my purpose for building is to shorten my int main so all it does is have about 4 function calls rather than everything in there.

Sorry for the trouble

Here is my current code and the text files attached to this post.

Anything that has a cout (other than errors) is me trying to debug the code and understand why certain values are not going through.

I though I would share this link for design of plugin architecture, since you mentioned it somewhere :)

I though I would share this link for design of plugin architecture, since you mentioned it somewhere :)

Thanks, I need to create the code for my project and unfortunately, I don't have enough time to look at something like that (implements ideas beyond my current understanding). Thank you for your help however.

Thanks, I need to create the code for my project and unfortunately, I don't have enough time to look at something like that (implements ideas beyond my current understanding). Thank you for your help however.

We always stretch our understanding don't we? Anyway, the link have more to do of design technique than coding. so you may well read it or ignore it. it is your prerogative :)

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.