Object Oriented Philosophy

Hi,
In am new here. Pardon my english, I'll try to do my best.
I don't know exactly how to title my question, neither how to formulate it, so I am just going to use a general example:

Imagine that in order to represent a mathematical world, I first create a "Space" class, that will contain secondary objects, such as "Point", "Line", etc.

Example 1: In order to know the distance between 2 Points, what would be the best choice :

Writing a method
distance(Point* a, Point* b)
in my class "Space" ?

OR

Writing a method
distanceTo(Point* b)
in my class "Point" ?

------

Example 2: I choose to give my "Line" class 2 parameters.

1
2
Point* _start;
Point* _end;


Again, what would be the best choice :

Writing a method
createLine(Point* a, Point* b)
in my class "Space" ?

OR

Writing a method
createLineTo(Point* b)
in my class "Point" ?

------

Examples like these go on and on...

This question can appear if you want to create a molecular simulation.
Should one put "Atom" and "Bond" classes in the "Molecule" class, or put "Bond" in "Atom" and "Atom" in "Molecule"?

In fact, my question is:

Which "level of deepness" is generally better?
-"Top" objects that contain many smaller, ones and own all the methods to make then interact?
-Objects inside objects inside objects?

Is there any theory about it, or is it just a personal choice?

Thanks in advance !
this method distance(Point* a, Point* b)
is predestined for a static const method and
this method distanceTo(Point* b) is typical for a member method.

so it depends on what you need/want ;)

regards
I would do something like this:

> Example 1:
1
2
3
4
5
6
struct point
{
    // ...
    double distance_to( const point& that ) const ;
    // ...
};


Or if I want to get cute:
double operator- ( const point& a, const point& b ) ;


> Example 2:
1
2
3
4
5
6
7
8
9
struct line_segment
{
    // ...
    explicit  line_segment( const point& first, const point& second ) : a(first), b(second) {}
    // ...
      private:
          point a ;
          point b ;
};


Lines and points are 'objects' all right; but I would treat them as user-defined value types a la std::string - without even a hint of 'object-orientedness' about them.
I'd imagine those are all matters of personal preference, but that's just me. I'm not much of an expert at O-o. Also, please keep inheritance in mind. I'm guessing you'd have a molecule object that had atom objects and bond objects that somehow interact with two atom objects, maybe store the atoms in a vector of atom objects and each bond contains an array of two ints which denote the locations in the atom vector at which the two atoms it connects are stored?

Anyways, one thing to keep in mind that people always tell you is that C++ is not Object-oriented (or it is, depending on your definition.) It supports Object-oriented programming, but one can write code in C++ without having to call on Object-orientation. Java differs here in that any valid programs have some level of Object-orientation.
Style-wise, I might implement subtraction of 2 points to return another point representing the vector between them. Besides that, I think JLBorges' use of const references as parameters is the way to go, and will give cleaner code when used.

It definitely is a personal preference where you want to handle the distance logic, but as a possibility:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59

class Point;

class SpatialObject
{
public:
	virtual double DistanceTo(const Point & destPt) const = 0; // Pure virtual, require subclasses to implement
};

class Point : public SpatialObject
{
public:
	double DistanceTo(const Point &destPt) const
	{
		return (*this - destPt).Magnitude();
	}

	Point operator-(const Point &subPt) const
	{
		Point returnPt;
		returnPt.x = x - subPt.x;
		returnPt.y = y - subPt.y;
		returnPt.z = z - subPt.z;
		return returnPt;
	}

	Point Cross(const Point &crossPt) const
	{
		Point returnPt;
		returnPt.x = y * crossPt.z - z * crossPt.y;
		returnPt.y = z * crossPt.x - x * crossPt.z;
		returnPt.z = x * crossPt.y - y * crossPt.x;
		return returnPt;
	}

	double Magnitude() const
	{
		return sqrt(x*x+y*y+z*z);
	}

	double x, y, z;
};

class Line : public SpatialObject
{
public:
	double DistanceTo(const Point &destPt) const
	{
		// Copied (untested) from wolfram alpha
		// Note: this is for a line, NOT a line segment
		double numerator = (p2 - p1).Cross(p1 - destPt).Magnitude();
		double denominator = (p2 - p1).Magnitude();
		return numerator/denominator;
	}

protected:
	Point p1;
	Point p2;
};


I like this type of approach, because it allows you perform operations on objects without caring the type of object you have.
Last edited on
Topic archived. No new replies allowed.