I'm working on a really over engineered matrix calculator for school and hit a brick wall with the very last function I need. The full version of the transpose()
is supposed to re-arrange my matrix and to switch collumns and rows around.
I posted this question earlier with a snippet but was asked to write a minimum reproducable sample. This isn't very "minimum" but I tried.
So. I have a std::vector<std::unique_ptr<Interface>>
that can hold objects of types Sub1
and Sub2
.
In the full version I have a class that bypasses Interface
and works fine since it only holds Sub2
objects.
However I can't seem to get it to work when there are multiple types in the vector. Nothing I've tried in the past few hours has done anything.
#include <iostream>
#include "main.h"
#include <memory>
#include <utility>
#include <vector>
#include <sstream>
//this is the one that won't work
Super Super::transpose() const {
Super newMatrix = *this;
int i = 1;
for(auto& elem : elements){
*elem = *newMatrix.elements[i];
i--;
}
return *this;
}
int main() {
std::vector<std::unique_ptr<Interface>> newMatrix;
newMatrix.push_back(std::unique_ptr<Sub1>(new Sub1('x')));
newMatrix.push_back(std::unique_ptr<Sub2>(new Sub2(1)));
Super mtx(std::move(newMatrix),2 );
std::cout << mtx << std::endl;
mtx.transpose();
std::cout << mtx;
return 0;
}
//busywork from here on
Super::Super(std::vector<std::unique_ptr<Interface>> matrix, int pN){
elements = std::move(matrix);
n = pN;
}
std::unique_ptr<Interface> Sub1::clone() const {
char newVal = val;
return std::unique_ptr<Sub1>(new Sub1(newVal));
}
std::unique_ptr<Interface> Sub2::clone() const {
int newVal = i;
return std::unique_ptr<Sub2>(new Sub2(newVal));
}
Sub1::Sub1(char pVal) {
val = pVal;
}
Sub2::Sub2(int pI) {
i = pI;
}
std::string Sub1::toString() const {
std::stringstream ss;
ss << val;
return ss.str();
}
std::string Sub2::toString() const {
std::stringstream ss;
ss << i;
return ss.str();
}
std::ostream &operator<<(std::ostream &os, const Super &matrix) {
os << "[";
int i = 0;
for (auto &elem : matrix.elements) {
os << elem->toString();
if (i < matrix.n - 1) {
os << ",";
}
i++;
}
os << "]";
return os;
}
Super::Super(const Super &matrix) {
n = matrix.n;
for (auto &elem : matrix.elements) {
std::unique_ptr<Interface> newElem = elem->clone();
elements.push_back(std::move(newElem));
}
}
And heres the header
#ifndef EXAMPLE_MAIN_H
#define EXAMPLE_MAIN_H
#include <memory>
#include <vector>
class Interface{
public:
virtual ~Interface() = default;
virtual std::unique_ptr<Interface> clone() const = 0;
virtual std::string toString() const = 0;
};
class Super{
private:
std::vector<std::unique_ptr<Interface>> elements;
int n = 2;
public:
Super(std::vector<std::unique_ptr<Interface>> elements, int n);
Super(const Super &matrix);
Super transpose() const;
friend std::ostream &operator<<(std::ostream &os, const Super &matrix);
};
class Sub1: public Interface{
private:
char val;
public:
Sub1(char pVal);
std::string toString() const override;
std::unique_ptr<Interface> clone() const override;
};
class Sub2: public Interface{
private:
int i;
public:
Sub2(int pI);
std::string toString() const override;
std::unique_ptr<Interface> clone() const override;
};
std::ostream &operator<<(std::ostream &os, const Super &matrix);
#endif //EXAMPLE_MAIN_H
Aucun commentaire:
Enregistrer un commentaire