Я сомневаюсь в полиморфизме в c++. У меня есть следующая структура:
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()
{
}
и 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;
}
Теперь для нас действительно интересны операторы перегрузки <<. Мне нужно хранить несколько кватернионов и комплексов внутри вектора в QStore и после списка всех сохраненных объектов. Поскольку вы можете видеть, что Complex наследует кватернионы, а затем по методу add в QStore, я получаю только кватернионы. Что происходит, когда я вставляю некоторые объекты и показываю их, на экране отображаются только кватернионы. Мой вопрос: как сделать, чтобы отличить их?
Большое вам спасибо и жаль бедного английского. Phsil
Я решил проблему. На самом деле я начал использовать вектор, но нашел, как его решить без векторов. Мой новый класс QStore:
#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
Проблема заключалась в том, что ранее я создал вектор QStore следующим образом:
Quaternions *qstore;
и мне нужно было создать в этой форме:
Quaternions **qstore;
потому что в этом методе:
void QStore::list()
{
for (int i = 0; i< count; i++)
{
qstore[i]->toString();
cout << endl;
}
}
Мне нужно указать правильный экземпляр Quaternion one (Complex или Quaternion), а затем мне нужен указатель указателя для возможности доступа к экземпляру toString сложного экземпляра, хранящегося в векторе Quaternions, и не все время просто доступ toString кватерниона, это была моя первоначальная проблема.
Спасибо, что помогли мне.
: D