What a way is more OOPer ?

Posted on 2002-07-06
Last Modified: 2010-04-01
I must to implement Quaternion and Complex numbers classes. I began so:

template <class T>
class Quaternion
  Quaternion(); // few kinds of Ctors
  T w,x,y,z; // w+xi+yj+zk;

I have 3 ways to continue:

1-st way:

template <class T>
class Complex1
   Complex1(); // few kinds of Ctors

   Quarterion<T> q;  // I use the q as complex number
   // and its y,z fields initialized by zero;

2-nd way:
template <class T>
class Complex2:public Quarterion<T>
  Complex2(T a, T b):Quarterion(a,b,0,0){}
  // yet few needed Ctors

3-rd way:
template <class T>
class Complex3:private Quarterion<T>

//  Additional question (accordingly I add points):

  How can I to declare here function from Quarterion class so that they should public (I don't want that user of    Complex3 class should be able to use function from Quarterion beside of function I'll permit for using)?

What way from these is prefer ?

Thank you.
Question by:VR_
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2

Expert Comment

ID: 7134050
This is known as the ellipse-circle dilemma (or the rectangle-square dilemma). The basic answer is that you should do what makes more sense in your context, and not necessarily reflect what mathematicians consider to be the true taxonomy.

For more info see

Accepted Solution

jasonclarke earned 100 total points
ID: 7135060
I think the Liskov Substitution Principle (also mentioned in the link yonat gave above), shows that at least public inheritance is probably the wrong answer in this case.

LSP is the principle of substitutability,  it states that for public inheritance you should be able to use (in this case) a Complex number *anywhere* you can use a Quaternion.

This is probably not the case - for a Complex number you require that the y & z fields are presumably always zero.  Therefore if any operation on Quaternion violates this condition, then inheritance is a bad choice.  e.g. if there is a public method on a Quaternion that changes the y or z fields, then public inheritance is the wrong choice.

Private inheritance *might* be the right answer, but only if either i) you need to access protected methods of the base class or ii) you need to override virtual methods of the base class.

As such, the right answer is most likely to be containment/aggregation (your 2nd way), although as yonat suggests, this very much depends on the details of what you are doing.

Author Comment

ID: 7137290
I implement it through aggregation, although before it I tried private inheritance, where I meet with next problem:
I've adjusted access control to member function which I need in Complex for example:

template <class T>
class Quaternion{
public: Quaternion<T> operator+ (const Quaternion<T> q);

template <class T>
class Complex:private Quaternion<T>{
using Quaternion<T>::operator+;

and in user code:

Comlpex c1(1,2),c2(3,4),c3;
cout << (c1+c2);

// of course I have comp. error. So, although I have access to op+ in Quaternion I cannot use it with Complex parameters !
I tried partialy solution as definition
operator Quaternion<T>(), but anyway returned value is Quaternion<T>  :(

Expert Comment

ID: 7137664
> So, although I have access to op+ in Quaternion I
> cannot use it with Complex parameters !
> I tried partialy solution as definition

it just won't work as you have it, this kind of exposure of Quaternions methods is a bad idea... how will you deal with:

Quaternion c1;
Complex    c2, c3;
c3 = c1 + c2;

this would be bad.  

This is exactly one of the cases I described above... substitutability fails here.  (and by making Quaternions methods public, you are in effect implementing a kind of selective public inheritance).

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
maze travler 6 66
Embarcadero C++ Builder XE2 TDateTime 8 80
How to convert MFC::CString to UTF8 wchar_t* 10 371
Safe conversion? 4 75
  Included as part of the C++ Standard Template Library (STL) is a collection of generic containers. Each of these containers serves a different purpose and has different pros and cons. It is often difficult to decide which container to use and …
Introduction This article is a continuation of the C/C++ Visual Studio Express debugger series. Part 1 provided a quick start guide in using the debugger. Part 2 focused on additional topics in breakpoints. As your assignments become a little more …
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

735 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question