C++ 从具有运算符重载的类派生
我想创建一个类集合,这些类的行为类似于数学向量,因此将一个对象乘以一个标量将每个字段乘以该数量,等等。问题是我希望字段具有实际名称,而不是作为索引处理 我实现这一点的最初想法是使用重载创建基类Rn,然后使用漂亮的名称创建派生类。大概是这样的:C++ 从具有运算符重载的类派生,c++,templates,C++,Templates,我想创建一个类集合,这些类的行为类似于数学向量,因此将一个对象乘以一个标量将每个字段乘以该数量,等等。问题是我希望字段具有实际名称,而不是作为索引处理 我实现这一点的最初想法是使用重载创建基类Rn,然后使用漂亮的名称创建派生类。大概是这样的: #include <iostream> #include <algorithm> using namespace std; template<int N, class X=double> struct Base{
#include <iostream>
#include <algorithm>
using namespace std;
template<int N, class X=double>
struct Base{
X xs[N];
Base(){};
Base(X *data){
copy(data, data+N, xs);
}
Base operator*= (double d){
for(int i=0; i<N; i++){
xs[i] *= d;
}
return *this;
}
Base operator* (double d){
Base answer = *this;
answer *= d;
return answer;
}
//also operators for +=, +, multiplication from left, maybe [] too
};
struct Derived : public Base<2>{
Derived(double a, double b){
foo() = a;
bar() = b;
}
double &foo(){ return xs[0]; }
double &bar(){ return xs[1]; }
};
int main()
{
//this is OK:
double data[2] = {0.0, 2.0};
Base<2> b(data);
b = b*17.0;
cout << b.xs[0] << endl;
//I can't do this:
Derived x(0.0, 2.0);
x = x*17.0;
cout << x.foo() << endl;
return 0;
}
#包括
#包括
使用名称空间std;
模板
结构基{
xxs[N];
Base(){};
基数(X*数据){
复制(数据,数据+N,xs);
}
基本运算符*=(双d){
对于(inti=0;i我认为使用枚举或静态常量来命名字段会更好
e、 例如,静态常量int字段_NAME=0;
静态常量int字段_NAME2=1
然后您可以使用std::valarray或boost::ublas::vector/matrix类型来利用现有代码并获得高质量的性能向量操作来引导。您的基本运算符(*在本例中为)可以接受派生对象,但它们返回一个基,该基不能用作派生默认赋值运算符中的右操作数。解决此问题的最简单方法是向派生添加一个赋值运算符,该运算符将采用一个基:
Derived& operator= (const Base<2>& other)
派生运算符=(常量基和其他)
您必须将其添加到任何派生类中,但实现相当简单(您可以在Base中使用void CopyOtherBase函数来执行复制,并让all operator=调用它并返回*this)。我将只讨论技术难点,而不讨论这是否是一个好主意
问题是,运算符*of Derived的结果是一个基,而运算符=of Derived(这是一个默认运算符=)不知道如何“吃”一个基
一个简单的解决方案是创建一个派生的构造函数,该构造函数获取一个基,并执行正确初始化自身所需的任何操作。这将允许将一个基动态转换为派生的,并适用于除基之外的所有其他派生运算符
类似于-
Derived(const Base<2>& B) : Base<2>( B )
{
}
派生(常量基&B):基(B)
{
}
模板元编程有一个有趣的想法,就是用数学向量来解决这类问题,但可能无法解决零件命名的问题
David Abrahams,Aleksey Gurtovoy:C++模板元编程:从Boost和Excel中的概念、工具和技术,Addison Wesley,ISBN 031-1-227 25-5/P>< P>,
所有重载运算符,除了
赋值(运算符=)是继承的
通过派生类
这可能是您的问题吗?memcpy通常是个坏主意。如果base不是POD,代码可能会严重中断。更喜欢使用更惯用的:派生的(const base&b):base(b){}这应该返回派生的(*尤其是this)。它不允许operatorX=,因为我相信您需要提供完整的外观。当然,您是对的。谢谢您的更正,我修正了我的答案。
Derived(const Base<2>& B) : Base<2>( B )
{
}