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。看着它工作吧

在中,您可以找到以下项目:

  • 考虑将虚拟功能设置为非公共功能,将公共功能设置为非虚拟功能。68
  • 我认为,尽管你的问题并不具体涉及公共/私人方面,但其中的理由仍在这里。非
    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);
        }
    };