【问题标题】:How to create object of nameless derived class of my abstract class?如何创建我的抽象类的无名派生类的对象?
【发布时间】:2015-11-29 00:15:36
【问题描述】:

考虑以下 Java 程序:

abstract class Surprising
{       
    void fun()
    {
        System.out.println("fun() is invoked");
    }
}
class myclass
{
    public static void main(String args[])      
    {
        Surprising s=new Surprising() { };
        s.fun();
    }
}

在这里,我正在创建我的抽象类 Surprising 的无名子类的对象,而不是抽象类的对象,因为它不允许在 Java 中创建抽象类的对象。

什么是等效的 C++ 程序?是否可以在 C++ 中做到这一点?如果是,怎么做?如果不是,为什么不允许?

【问题讨论】:

    标签: java c++ inheritance abstract-class pure-virtual


    【解决方案1】:

    假设我们有课程A

    class A
    {
        ...
    };
    

    现在要创建它的派生词,我们使用例如

    class B : public A
    {
        ...
    };
    

    现在要创建一个匿名类的对象,我们只是不提供类名:

    class
    {
        ...
    } anon_object;
    

    最后我们结合继承和匿名类这两种方式:

    class : public A
    {
        ...
    } anon_a_derived_object;
    

    【讨论】:

      【解决方案2】:

      在 C++ 中,Surprising 类不会是抽象,因为它定义了它的所有成员。如果你想要一个 abstract (即不可实例化)类,至少让它的一个成员成为纯虚拟的。喜欢这里:

      class Surprising
      {
      public:
          virtual void fun()=0;
      };
      

      然后您可以在创建实例的匿名类中定义成员,然后在该实例上调用新定义的成员函数:

      #include <iostream>
      
      int main()
      {
          class  : public Surprising
          {
          public:
              virtual void fun() { std::cout << "Surprise!" << std::endl; }
          } inst_;
          inst_.fun();
      
          return 0;
      }
      

      【讨论】:

      • 这与问题中的示例有很大的不同。现在每个匿名用户都必须实现fun 方法。我建议添加一个额外的虚拟方法,以便 Surprising 类仍然具有 fun 的实现
      • 没有必要这样做,我只是这样做是因为我觉得 OP 有特定的理由将Surprising 抽象化,即防止实例化。也可以在Surprising 中定义fun() 函数,然后从中派生一个类,但是如果派生类不添加或更改功能,那么子类化的意义何在?
      • &lt;Nit-pick&gt; 让匿名类使用override 关键字而不是virtual 会更好。 &lt;/Nit-pick&gt;干杯
      【解决方案3】:

      在将类声明为new 表达式的一部分的意义上,您不能像在Java 中那样即时执行此操作。但是你可以在函数内部创建一个本地类并使用它:

      void main(int argc, char **argv)
      {
        class MySurprising : public Surprising {};
        MySurprising s;
      }
      

      【讨论】:

      • 更相似的是匿名struct : Surprising {} s; s.fun();
      • @Walter 这就是其他答案所显示的。我会离开我的完整感。例如,这让您可以选择动态分配。
      【解决方案4】:

      与此问题相关的 Java 和 C++ 之间存在一些差异。我试图生成与所讨论的 Java 代码最匹配的 C++ 代码。

      #include <iostream>
      
      class Surprising           // class is abstract since it has pure virtual method
      {
      public:
        virtual void fun() = 0;  // pure virtual method makes the class abstract
      };
      
      // we can define the pure virtual method, but not in class
      inline void Surprising::fun()
      {
        std::cout<<"fun() is invoked\n";
      }
      
      int main()
      {
        struct : Surprising      // anonymous derived class
        {
          void fun()             // we must provide an implementation of fun()
          {                      // for otherwise this class remains abstract and
            Surprising::fun();   // cannot be instantinated
          }
        } s;                     // object of anyonmous class
        s.fun();
      }
      

      【讨论】:

        猜你喜欢
        • 2013-11-30
        • 2013-08-30
        • 1970-01-01
        • 1970-01-01
        • 2013-12-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-11-26
        相关资源
        最近更新 更多