0

I have a doubt about polymorphism in c++. I have the following structure:

Quaternions.h

#ifndef QUATERNIONS_H
#define QUATERNIONS_H

#include <math.h>
#include <ostream>

using namespace std;

class Quaternions
{
private:
    float z;
    float y;

protected:
    float w;
    float x;

public:

    Quaternions();
    Quaternions(float w, float x, float y, float z);


    float module() const;
    Quaternions conjugate();

    Quaternions operator +(const Quaternions quat);
    Quaternions operator -(const Quaternions quat);
    Quaternions operator *(const Quaternions quat);
    Quaternions operator /(const Quaternions quat);
    friend ostream& operator <<(ostream& os, const Quaternions& quat);


    float getX() const;
    float getW() const;
    void setX(float x);
    void setW(float w);
    float getY() const;
    float getZ() const;
    void setY(float y);
    void setZ(float z);

    ~Quaternions();
};

#endif

Quaternions.cpp

#include "Quaternions.h"


Quaternions::Quaternions(){

    x = 0;
    y = 0;
    z = 0;
    w = 0;
}

Quaternions::Quaternions(float w, float x, float y, float z) : x(x), y(y), z(z), w(w){

}



float Quaternions::module() const {

    return sqrt(pow(x, 2) + pow(y, 2) + pow(z, 2) + pow(w, 2));
}

Quaternions Quaternions::conjugate(){

    Quaternions conj;

    conj.setX(-x);
    conj.setY(-y);
    conj.setZ(-z);
    conj.setW(w);

    return conj;

}

Quaternions Quaternions::operator +(const Quaternions quat){

    Quaternions sum;

    sum.setX(x + quat.getX());
    sum.setY(y + quat.getY());
    sum.setZ(z + quat.getZ());
    sum.setW(w + quat.getW());

    return sum;
}

Quaternions Quaternions::operator -(const Quaternions quat){

    Quaternions sub;

    sub.setX(x - quat.getX());
    sub.setY(y - quat.getY());
    sub.setZ(z - quat.getZ());
    sub.setW(w - quat.getW());

    return sub;
}


Quaternions Quaternions::operator *(const Quaternions quat){

    Quaternions mult;

    mult.setX(w * quat.getX() + x * quat.getW() + y * quat.getX() - z * quat.getY());
    mult.setY(w * quat.getY() - x * quat.getZ() + y * quat.getW() + z * quat.getX());
    mult.setZ(w * quat.getZ() + x * quat.getY() - y * quat.getX() + z * quat.getW());
    mult.setW(w * quat.getW() - x * quat.getX() - y * quat.getY() - z * quat.getZ());

    return mult;
}

Quaternions Quaternions::operator /(const Quaternions quat){

    Quaternions div;

    div.setX((w * quat.getW() + x * quat.getX() + y * quat.getY() + z * quat.getZ()) 
        / (pow(quat.getW(), 2) + pow(quat.getX(), 2) + pow(quat.getY(), 2) + pow(quat.getZ(), 2)));
    div.setY((x * quat.getW() - w * quat.getX() - z * quat.getY() + y * quat.getZ())
        / (pow(quat.getW(), 2) + pow(quat.getX(), 2) + pow(quat.getY(), 2) + pow(quat.getZ(), 2)));
    div.setZ((y * quat.getW() + z * quat.getX() - w * quat.getY() - x * quat.getZ())
        / (pow(quat.getW(), 2) + pow(quat.getX(), 2) + pow(quat.getY(), 2) + pow(quat.getZ(), 2)));
    div.setW((z * quat.getW() - y * quat.getX() - x * quat.getY() - w * quat.getZ())
        / (pow(quat.getW(), 2) + pow(quat.getX(), 2) + pow(quat.getY(), 2) + pow(quat.getZ(), 2)));

    return div;
}

ostream& operator <<(ostream& os, const Quaternions& quat){

    return os << "q = " << quat.getX() << "i + " << quat.getY() << "j + " << quat.getZ() << "k + " << quat.getW();
}


float Quaternions::getX() const{
    return x;
}

float Quaternions::getY() const{
    return y;
}

float Quaternions::getZ() const{
    return z;
}

float Quaternions::getW() const{
    return w;
}


void Quaternions::setX(float x) {
    this->x = x;
}

void Quaternions::setY(float y) {
    this->y = y;
}

void Quaternions::setZ(float z) {
    this->z = z;
}

void Quaternions::setW(float w) {
    this->w = w;
}

Quaternions::~Quaternions()
{
}

Complex.h

#ifndef COMPLEX_H
#define COMPLEX_H

#include "Quaternions.h"
class Complex :
    public Quaternions
{
public:
    Complex();
    Complex(float x, float y);

    Complex conjugate();
    float module() const;

    Complex operator +(const Complex comp);
    Complex operator -(const Complex comp);
    Complex operator *(const Complex comp);
    Complex operator /(const Complex comp);
    friend ostream& operator <<(ostream& os, const Complex& comp);


    ~Complex();
};

#endif

Complex.cpp

#include "Complex.h"

Complex::Complex() : Quaternions(0.0, 0.0, 0.0, 0.0)
{

}

Complex::Complex(float x, float y) : Quaternions(x, y, 0.0, 0.0)
{
}

Complex Complex::conjugate(){
    Quaternions a(getW(), getX(), 0.0, 0.0);
    a = a.conjugate();
    return Complex(a.getW(), a.getX());
}

float Complex::module() const{

    return Quaternions(getW(), getX(), 0.0, 0.0).module();
}


Complex Complex::operator +(const Complex comp){
    Quaternions a(getW(), getX(), 0.0, 0.0);
    Quaternions b(comp.getW(), comp.getX(), 0.0, 0.0);
    Quaternions soma = a + b;
    return Complex(soma.getW(), soma.getX());
}

Complex Complex::operator -(const Complex comp){
    Quaternions a(getW(), getX(), 0.0, 0.0);
    Quaternions b(comp.getW(), comp.getX(), 0.0, 0.0);
    Quaternions sub = a - b;
    return Complex(sub.getW(), sub.getX());
}

Complex Complex::operator *(const Complex comp){
    Quaternions a(getW(), getX(), 0.0, 0.0);
    Quaternions b(comp.getW(), comp.getX(), 0.0, 0.0);
    Quaternions mult = a * b;
    return Complex(mult.getW(), mult.getX());
}

Complex Complex::operator /(const Complex comp){
    Quaternions a(getW(), getX(), 0.0, 0.0);
    Quaternions b(comp.getW(), comp.getX(), 0.0, 0.0);
    Quaternions mult = a / b;
    return Complex(mult.getW(), mult.getX());
}

ostream& operator <<(ostream& os, const Complex& comp){

    return os << "c = " << comp.getW() << " + " << comp.getX() << "i";
}

Complex::~Complex()
{
}

and QStore

#include "QStore.h"


QStore::QStore() : size(0), count(0)
{
    qstore = NULL;
}

QStore::QStore(int size) : size(size), count(0)
{
    qstore = new Quaternions[size];
}

void QStore::add(Quaternions *quat){
    if (count < size){
        qstore[count++] = *quat;
    }
}

void QStore::list()
{
    for (int i = 0; i<size; i++)
    {
        cout << qstore[i] << endl;
    }
}

QStore::~QStore()
{
    delete[] qstore;
}

What really interests for us now is the overload operators <<. I need store several quaternions and complexes inside of a vector in QStore and after list all the objects stored. As you can see Complex inherits quaternions and then on the method add in QStore I receive only quaternions. What is happening is when I insert some objects and show them, just quaternions are showed on the screen. My question is, how doing for distinguish them?

Thank you very much and sorry for the poor english. Phsil

Pablo Silva
  • 47
  • 10
  • Post your QStore and Complex header files. I also see no usage of "vector" in your code. – PaulMcKenzie Apr 06 '14 at 17:10
  • "I have a doubt about polymorphism in c++" — that's not accidental. OO-style base/derived polymorphism doesn't lend itself well to cases like this. Don't derive Complex from Quaternion, it makes no sense. – n. m. could be an AI Apr 06 '14 at 19:59
  • possible duplicate of [What is the slicing problem in C++?](http://stackoverflow.com/questions/274626/what-is-the-slicing-problem-in-c) – BartoszKP Apr 06 '14 at 20:06
  • What is "qstore"? Also, from what you posted, I don't see any real polymorphism. I only see one class derived from another. That alone does not make C++ polymorphic. Where are the virtual functions? – PaulMcKenzie Apr 06 '14 at 20:32

1 Answers1

0

I solved the problem. Actually I started using vector, but I found how to solve it without vectors. My new class QStore is:

#ifndef QSTORE_H
#define QSTORE_H

#include "Quaternions.h"
#include <vector>

class QStore
{
private:
int count;
std::vector<Quaternions*> qstore;
public:
QStore();
void add(Quaternions *quat);
void list();
~QStore();
};

#endif

The problem was that previously I created a vector of QStore as follows:

Quaternions *qstore;

and I needed to create in this form:

 Quaternions **qstore;

because in this method:

void QStore::list()
{
for (int i = 0; i< count; i++)
{
    qstore[i]->toString();
    cout << endl;
}
}

I need to point for the correct instance of the Quaternion one (Complex or Quaternion) and then I need a pointer of a pointer for be able to access the toString of a Complex instance stored in a vector of Quaternions and not all the time just access the toString of the Quaternion one, that was my initial problem.

Thank you for trying help me.

:D

Pablo Silva
  • 47
  • 10