Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/145.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 强制派生类实现私有方法_C++_Inheritance - Fatal编程技术网

C++ 强制派生类实现私有方法

C++ 强制派生类实现私有方法,c++,inheritance,C++,Inheritance,有没有办法,我可以强制派生类通过私有函数实现接口。我想要的是以下内容 class base{ private: virtual void do_something() = 0; // This can be private/public/protected }; 派生类必须提供非公共的do\u something()的实现。正如您所猜测的,我的目标是让用户给出一个函数的实现,但确保基类是将调用它的类,并且类派生的对象:public base{…}将永远无法单独调用do_somethin

有没有办法,我可以强制派生类通过私有函数实现接口。我想要的是以下内容

class base{
private:
    virtual void do_something() = 0; // This can be private/public/protected
};
派生类必须提供非公共的
do\u something()
的实现。正如您所猜测的,我的目标是让用户给出一个函数的实现,但确保基类是将调用它的类,并且
类派生的对象:public base{…}
将永远无法单独调用
do_something()


编辑:只想添加,
类派生:base
将由用户编写,而不是由我编写。用例是确保基类的函数控制何时调用do_something()。

其思想是,您可以要求派生类在构造函数调用中传递函数对象,而不是将
do_something
声明为类成员。但这很难看——我宁愿放弃“不能从派生调用”的要求,而使用
受保护的

#include <functional>
#include <iostream>

class base {
public:
  base(std::function<void()> do_something) : _do_something(do_something) {}
  void act() {
    _do_something();
  }

private:
  std::function<void()> _do_something;
};

class derived : public base {
public:
  derived() : base([&]{std::cout << "impl: " << prop1 << ", " << prop2 << std::endl;}) {}

private:
  int prop1;
  int prop2;
};

int main(int argc, char* argv[]) {
  derived d;
  d.act();
  return 0;
}
#包括
#包括
阶级基础{
公众:
base(std::function do_something):_do_something(do_something){
无效法案{
_做某事;
}
私人:
std::函数_do_某事;
};
派生类:公共基{
公众:

派生():基([&]{std::coutTL;DR:No


给定

您不能强制派生类将
do\u something
实现为私有。以下是合法的:

struct derived : base {
    void do_something() { ... }  // public
};

即使你可以强制它是私有的,一个类也可以调用它自己的私有方法。这与你的要求背道而驰,“派生的
类的对象:
将永远无法单独调用
do\u something()


即使您可以强制派生类实现一个方法而不调用它,它们仍然可以这样处理:

struct derived2 : base {
    void do_something_impl() { .... }
private:
    void do_something() { do_something_impl(); }
};
现在他们可以直接调用
do\u something\u impl()

你不能这么做。
请看@melpomene给出的漂亮答案


如果问题是它将被具有派生类引用的类公开访问,则可以执行以下操作:

class base {
private:
    virtual void do_something() = 0;
};

template<typename T>
class intermediate: public base, private T {
    void do_something() override {
        T::do_something();
    }
};

class derived {
public:
    void do_something() { }
};

int main() {
    auto *d = new intermediate<derived>{};
    base *b = d;
    // not allowed, it's private
    // d->do_somerhing();
    // b->do_something();
}
类基{
私人:
虚空do_something()=0;
};
模板
中级:公共基地,私人T{
void do_something()覆盖{
做某事;
}
};
类派生{
公众:
void do_something(){}
};
int main(){
auto*d=新中间层{};
基*b=d;
//不允许,这是私人的
//d->dou_somerhing();
//做点什么;
}
在一定范围内,您甚至可以模拟继承的数据成员(我知道,它们根本不是继承的,但朋友可以在这里提供帮助):

模板
中级:公共基地,私人T{
朋友T;
void do_something()覆盖{
T::做点什么(*这个);
}
私人:
int foo;
};
类派生{
公众:
无效做某事(中间和参考){
ref.foo=42;
}
};

派生类无权访问基类的
private
成员。如果派生类必须重写
do\u something()

class base
{
protected:
    virtual void do_something() = 0;
};
如果
do\u something()

class base
{
private:
    void do_something()
    {
        //...
        actually_do_something();
        //...
    }

protected:
    virtual void actually_do_something() = 0;
};

您希望这样做的实际用例是什么?@πάνταῥεῖ 模板方法模式?你是说你不想
派生的
能够调用
做某事()
内部?我只希望基类中的方法能够调用派生类中的方法。这是为了控制执行顺序。@juanchopanza我通常使用
protected
来实现此模式。是的,第一种情况让我感到困惑。即使我在基类中将函数声明为私有虚函数,也会使用派生类可以重写它。我本来以为这是不可能的,但是显然代码编译了。所以它必须是合法C++。
class base
{
protected:
    virtual void do_something() = 0;
};
class base
{
private:
    void do_something()
    {
        //...
        actually_do_something();
        //...
    }

protected:
    virtual void actually_do_something() = 0;
};