在基类中使用抽象期望它是派生类?

发布于 2024-08-27 20:26:31 字数 652 浏览 7 评论 0原文

采取这个简单的代码:

class A{ 
  public: 
  virtual void foo() = 0; 
  void x(){ foo(); }
};
class B: public A{ foo(){ ... } };

main(){
  B b;
  b.x();
}

我想要的是构建一个抽象类,该类将具有一个函数,该函数将调用一个函数,期望它在派生类中实现

问题是我似乎无法使其工作,编译器说它无法编译,因为它找不到要在基类的 x() 中执行的 foo() 的引用(或类似的东西)。这可以吗?谁能给我举个例子吗?

编辑:似乎当“foo();”时它不起作用位于 A 类(基类)的析构函数内...
这让我很困惑。 =[

编辑2:这有多有趣。我刚刚创建了一个 callfoo(){ foo();现在它编译正常,但是如果我尝试直接从基类 A 的析构函数中调用纯抽象函数,它会给我错误......很奇怪。有人对此有任何想法吗? O_o

对此有什么帮助吗?

谢谢,
乔纳森

更新

它在析构函数之外工作。现在我很困惑。

尝试将“foo()”放入A(基)类的析构函数中,至少对我来说没有编译......

请问有什么帮助吗?

take this simple code:

class A{ 
  public: 
  virtual void foo() = 0; 
  void x(){ foo(); }
};
class B: public A{ foo(){ ... } };

main(){
  B b;
  b.x();
}

What I want is to build an abstract class that will have a function that will call a function expecting it to be implemented in the derived class

The question is that I can't seem to make that work, the compiler says it can't compile because it can't find the reference(or something like that) to the foo() to be executed in x() of the base class. Can this work? Can anyone give me an example of this?

EDIT: It seems that it just doesn't work when the "foo();" is inside the destructor of class A(the base one)...
It just got me confused. =[

EDIT2: how interesting this got. I just created a callfoo(){ foo(); } and now it compiles ok, but if I try to call the pure abstract function directly from within the destructor of Base class A, it gives me errors... weird. Anyone has any idea of this? O_o

any help on this please?

Thanks,
Jonathan

Update

It worked outside the destructor. Now I just got confused.

Try putting the "foo()" inside the destructor of the A(base) class, at least for me is not compiling...

any help plz?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

半仙 2024-09-03 20:26:31

没有什么可以阻止您这样做:

struct A {
    virtual ~A() {}
    virtual void f() = 0;
    virtual void g() { f(); }
};

struct B : A {
    void f() { std::cout << "B::f()" << std::endl; }
};

// ...
A* a = new B;
a->g(); // prints "B::f()"

至于从析构函数(或构造函数)调用纯虚函数:不要!它会调用未定义的行为。

§10.4/6

可以从抽象类的构造函数(或析构函数)调用成员函数;对于从此类构造函数(或析构函数)创建(或销毁)的对象,直接或间接对纯虚函数进行虚拟调用(10.3)的效​​果是未定义的。

There is nothing preventing you from doing that:

struct A {
    virtual ~A() {}
    virtual void f() = 0;
    virtual void g() { f(); }
};

struct B : A {
    void f() { std::cout << "B::f()" << std::endl; }
};

// ...
A* a = new B;
a->g(); // prints "B::f()"

As for calling a pure virtual function from the destructor (or constructor): Don't! It invokes undefined behaviour.

§10.4/6:

Member functions can be called from a constructor (or destructor) of an abstract class; the effect of making a virtual call (10.3) to a pure virtual function directly or indirectly for the object being created (or destroyed) from such a constructor (or destructor) is undefined.

指尖凝香 2024-09-03 20:26:31

它应该与一些语法修改一起工作。

#include <iostream>

class A { 
  public: 
  virtual ~A() {}
  virtual void foo() = 0; 
  void x() { foo(); }
};

class B: public A{ 
    void foo(){ std::cerr << "bingo!" << std::endl; } 
};

int main(){
  B b;
  b.x();
  return 0;
}

$ g++ -Wall -Weffc++ derived.cc 
$ ./a.out 
bingo!

这种技术是完全合法的。

It should work with a few syntactic modifications.

#include <iostream>

class A { 
  public: 
  virtual ~A() {}
  virtual void foo() = 0; 
  void x() { foo(); }
};

class B: public A{ 
    void foo(){ std::cerr << "bingo!" << std::endl; } 
};

int main(){
  B b;
  b.x();
  return 0;
}

$ g++ -Wall -Weffc++ derived.cc 
$ ./a.out 
bingo!

This technique is perfectly legal.

嘿咻 2024-09-03 20:26:31

似乎您正在寻找的是 模板方法模式的实现。

您需要使用指针,以利用多态性(从而避免消息... x is not a member of B)

#include <iostream>                                                             

class A{  
  public: 
    virtual void foo() = 0;  
    virtual void x(){ foo(); }
};  
class B: public A{  
        void foo(){ std::cout<<"this is b"<<std::endl; } 
};

int main(){
 A* b= new B();
 b->x();

 return 0;
 }   

Seems that what you are looking for is an implementation of the Template Method pattern.

You need to use pointers, in order to take advantage of polymorphism (thus avoiding the message ... x is not a member of B)

#include <iostream>                                                             

class A{  
  public: 
    virtual void foo() = 0;  
    virtual void x(){ foo(); }
};  
class B: public A{  
        void foo(){ std::cout<<"this is b"<<std::endl; } 
};

int main(){
 A* b= new B();
 b->x();

 return 0;
 }   
撩人痒 2024-09-03 20:26:31

理论上来说,效果一样好,但您应该向 B 类上的 foo() 添加返回类型

Well in theory that works just as fine, you should though add a return type to foo() on class B

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文