gpt4 book ai didi

c++ - 使 C++ 类与通用用户定义的输入一起工作

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:06:55 28 4
gpt4 key购买 nike

我觉得这个问题之前肯定有人问过,但我在谷歌上四处寻找却找不到答案。如果有请给我一个链接,我会删除这篇文章。

考虑这个代表我遇到的更大问题的最小示例。假设我像这样创建了一个简单的“Point”和“Printer”类:

class Point {
public:
double x, y;

Point() {x = y = 0;}
Point(double x, double y) {
this->x = x; this->y = y;
}
};

template<typename T>
class Printer {
public:
T* mData;
int mSize;

// Constructor
Printer(std::vector<T> &input) {
mData = &input[0];
mSize = input.size();
}

// Simple Print function
void Print() {
printf(" - Showing %d items\n", mSize);
for (int i = 0; i < mSize; i++) {
const T &item = mData[i];
printf(" - Item %d: (%lf, %lf)\n", i, item.x, item.y);
}
}
};

我可以像这样使用打印机类:

std::vector<Point> points; // fill the vector, and then...
Printer<Point> pointsPrinter(points); pointsPrinter.Print();

现在假设其他人出现并希望使用 Printer 类,其中声明了自己的“Point”类,如下所示:

class Pnt {
public:
double mX, mY;
// other stuff
};

如果他们尝试这样做:

vector<Pnt> pnts; // Fill the pnts, and then...
Printer<Pnt> pntsPrinter(pnts);
pntsPrinter.Print(); // COMPILE ERROR HERE!

显然这会失败,因为 Pnt 没有 x 或 y 成员。是否存在一种方法可以重写 Printer 类以适用于所有通用用户类型?我不想做的是将 Pnt vector 复制到点 vector 中。

编辑:

我能想到的唯一方法是传递函数指针。像这样:

template<typename T>
class Printer {
public:

T* mData;
int mSize;
double* (*mXFunc) (T*);
double* (*mYFunc) (T*);

Printer(std::vector<T> &input,
double* (*xFunc) (T*),
double* (*yFunc) (T*))
{
mData = &input[0];
mSize = input.size();
mXFunc = xFunc;
mYFunc = yFunc;
}

void Print() {
printf(" - Showing %d items\n", mSize);
for (int i = 0; i < mSize; i++) {
T &item = mData[i];
printf(" - Item %d: (%lf, %lf)\n", i, *mXFunc(&item), *mYFunc(&item));
}

}
};

// Could then use it like so
inline double* getXPointVal(Point *point) {return &point->x;}
inline double* getYPointVal(Point *point) {return &point->y;}
inline double* getXPntVal(Pnt *point) {return &point->mX;}
inline double* getYPntVal(Pnt *point) {return &point->mY;}

Printer<Pnt> pntPrinter(pnts, getXPntVal, getYPntVal);
Printer<Point> pointsPrinter(points, getXPointVal, getYPointVal);

pntPrinter.Print();
pointsPrinter.Print();

问题是它看起来很丑,而且还可能引入函数调用开销。但我想函数调用开销会被编译掉吗?我希望存在更优雅的解决方案...

最佳答案

如果选择cout而不是 printf要编写输出,您可以允许所有可打印类型为 << 定义重载运算符并在 Printer::print() 中一般使用它.重载可能如下所示:

std::ostream& operator<<(std::ostream &out, Point& p){
out << "Point(" << p.x << ", " << p.y << ")";
return out;
}

附带说明一下,我建议不要存储指向 vector 的指针。的内部存储和大小成员。如果 vector 需要重新分配,您的指针将悬空且无效。相反,您应该暂时将 vector 作为引用传递或保留常量引用。

关于c++ - 使 C++ 类与通用用户定义的输入一起工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38466578/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com