C++ 将私有参数中继到派生类虚拟方法
考虑以下两类:C++ 将私有参数中继到派生类虚拟方法,c++,inheritance,virtual-functions,C++,Inheritance,Virtual Functions,考虑以下两类: class Parent { private: char outputBuffer[100]; protected: virtual void WriteOutput() = 0; }; class Child : public Parent { private: double value1; double value2; void WriteOutput() { sprintf(outputBuffer, "
class Parent
{
private:
char outputBuffer[100];
protected:
virtual void WriteOutput() = 0;
};
class Child : public Parent
{
private:
double value1;
double value2;
void WriteOutput()
{
sprintf(outputBuffer, "%.2f %.2f", value1, value2);
}
};
父级定义了一个virtual
函数,然后在子级中实现该函数,其目的是将格式化字符串写入输出缓冲区
我的挑战是,我希望输出缓冲区不直接对子类可见。换句话说,我希望WriteOutput看起来像:
void WriteOutput()
{
myFcn("%.2f %.2f", value1, value2);
}
但是myFcn()
看起来像什么呢?它应该只传递给sprintf,但是sprintf中支持varags所需的语法让我感到困惑。是否可以传递数量可变的参数?我在示例中显示了两个值,但不同的子级将有不同的值数,因此我必须保留sprintf的vararg功能。请注意,性能在这里很重要,因此我不能有不必要的字符串副本
如果在这方面有更好的和更有效的替代方案,我可以考虑。谢谢。您可以使用新的变量模板。i、 e
#include <iostream>
#include <iomanip>
void write()
{ }
template<typename... Params>
void write(double toPrint, Params... args)
{
std::string str = "%.2f";
const int size = sizeof...(args);
if(size > 0U)
str += " ";
sprintf(outputBuffer, str.c_str(), toPrint);
write(args...);
}
调用是相同的,但您只使用一个sprintf
Call。看着它工作吧 在中,您可以找到以下项目:
virtual
方法应该说“外部”它做什么,而virtual
方法应该说它是如何做的
因此,它们不必具有相同的签名。事实上,这个怎么样:
class Parent
{
private:
char outputBuffer[100];
protected:
virtual void WriteOutputImp(char outputBuffer[100]) = 0;
public:
void WriteOutput()
{
WriteOutputImp(outputBuffer);
}
};
class Child : public Parent
{
private:
double value1;
double value2;
protected:
virtual void WriteOutputImp(char outputBuffer[100])
{
sprintf(outputBuffer, "%.2f %.2f", value1, value2);
}
};
<强>编辑< /强> As@ 5Gun12EdER正确(imHo)提到,当你在它的时候,你可以考虑将<代码> char…[ 100 ] < /代码>变成更安全的东西。这是完全正确的,但还有一点。
这就是你想要的吗?@chris,答案来自2009年。C++ 11有更好的可能性,而不是在下面使用<代码> vStAMTF,使用C++可变模板函数。这是引入可变模板时最常见的例子之一。由于函数是虚拟的
,因此模板
将不适用(直接)。@KonradRudolph同意。我认为这是一个非常好的答案,但是void writeOutputPutimp(char outputBuffer[100])
签名有误导性。我宁愿让函数接受指针和长度,并在内部使用snprintf
@5gon12eder谢谢,这听起来很合乎逻辑。因为这是一个正交点,所以为了避免混淆,我想我会把它作为一个后点。谢谢!
class Parent
{
private:
char outputBuffer[100];
protected:
virtual void WriteOutputImp(char outputBuffer[100]) = 0;
public:
void WriteOutput()
{
WriteOutputImp(outputBuffer);
}
};
class Child : public Parent
{
private:
double value1;
double value2;
protected:
virtual void WriteOutputImp(char outputBuffer[100])
{
sprintf(outputBuffer, "%.2f %.2f", value1, value2);
}
};