所以我在这里试图实现的是将派生的子类转换为从同一子类派生的另一个子类。到目前为止,这看起来不可能真正做到,但我仍然相信。
我的示例代码是:
#include <iostream>
#include <vector>
class BaseClass
{
public:
virtual void printFunction() = 0;
};
class printOne : public BaseClass
{
public:
void printFunction() override
{
std::cout << "Onen";
}
};
class printTwo : public BaseClass
{
public:
void printFunction() override
{
std::cout << "Twon";
}
};
int main()
{
std::vector<BaseClass *> baseClassVector;
printOne * one = new printOne;
baseClassVector.push_back(one);
printTwo * two = new printTwo;
baseClassVector.push_back(two);
}
所以我想用这个向量实际做的是,我想改变";一个";将索引0上的对象转换为"0";两个";对象现在这可以通过代码完成
delete baseClassVector[0];
printTwo * two = new printTwo;
baseClassVector[0] = two;
然而,据我所知,这是非常昂贵的,尤其是如果必须在运行时进行。我想知道是否还有其他方法可以做到这一点,或者与其他替代方案相比,成本是否值得。
提前感谢!
对于问题中的简化示例,使用更简单的std::variant
,只需完全避免基类:
class printOne
{
public:
void printFunction() const
{
std::cout << "Onen";
}
};
class printTwo
{
public:
void printFunction() const
{
std::cout << "Twon";
}
};
using printEither = std::variant<printOne, printTwo>;
void printFunction(const printEither& e)
{
std::visit([](auto& p) { p.printFunction(); }, e);
}
int main()
{
std::vector<printEither> eitherVector;
printOne one;
eitherVector.push_back(one);
printTwo two;
eitherVector.push_back(two);
eitherVector[0] = two;
for (auto& e: eitherVector)
printFunction(e);
}
在C++中重新使用对实际上不相关的类型的分配是一件很难正确编写的事情。进行分配更容易,也更可取。
从技术上讲;重建";作为一种不同类型的对象,尽管以下内容应该只是概念的证明,而不是设计或实践的建议。首先要付出的代价是放弃new/delete
的便利性,转而使用malloc/free
手动管理放置新的显式析构函数。
const size_t sz = max(sizeof(printOne), sizeof(printTwo));
BaseClass *either = (BaseClass *)malloc(sz); // allocate memory for objects
new(either) printOne(); // construct printOne object
printOne *one = dynamic_cast<printOne *>(either); // ... use printOne object
one->~printOne(); // destruct printOne object
new(either) printTwo(); // construct printTwo object
printTwo *two = dynamic_cast<printTwo *>(either); // ... use printTwo object
two->~printTwo(); // destruct printTwo object
free(either); // free memory used by objects