Is it possible to give a definition of a class in C++ during allocation, as is allowed in java

后端 未结 4 1795
无人及你
无人及你 2021-01-18 07:03

Or simply put

can I do some thing like

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

class B {
  public:
    A *a;
    b(){
       a = new A() { vo         


        
4条回答
  •  既然无缘
    2021-01-18 07:42

    Same answer as for the others, but if you wish to emulate such behavior you can (I don't recommend it though) :

        struct          Interface
        {
          virtual void  doStuff() const = 0;
          virtual       ~Interface() {}
        };
    
        #define newAnon(tmp_name, parents, body, args...)                       \
          ({                                                                    \
            class              tmp_name :                                      \
              parents                                                           \
            {                                                                   \
              body;                                                             \
            };                                                                  \
            new tmp_name(##args);                                               \
          })
    
        Interface       *getDefault()
        {
          return newAnon(__tmp__, public Interface,
    public:
                         virtual void doStuff() const {
                           std::cout << "Some would say i'm the reverse" << std::endl;
                         });
        }
    

    Beware though because you cannot have a static member in this new class, and that this is taking advantage of the Gcc/G++ statement expression : Statement-Exprs

    A solution for static member would be the following, imagine we want a static int i that increments itself in a few situations in our previous class tmp, this would look like this :

        struct          Interface
        {
          virtual void  doStuff() const = 0;
          virtual void  undoStuff() const = 0;
          virtual       ~Interface() {}
        };
    
        newAnon(__tmp__, Interface,
                         static int &i() {
                           static int i(0);
                           return i;
                         }
    
    public:    
                         virtual void doStuff() const {
                           std::cout << "call n°" << i()++ << std::endl;
                         }
    
                         virtual void undoStuff() const {
                           std::cout << "uncall n°" << i()-- << std::endl;
                         });
    

    The result is that all new pointers given by getDefault() will refer to the same integer. Note that using c++11's auto you can access all the public members as expected and use hierarchy to create a child of said type :

      auto tmp = newAnon(...);
    
      struct Try : decltype(*tmp+) {
        Try() { std::cout << "Lol" << std::endl; }
      };
    
      Try a; // => will print "Lol"
    

    Update: A more modern c++ (14-17) without extensions would be

    #define newAnon(code...) \
         [&](auto&&... args) {\
              struct __this__ : code;\
              return std::make_unique<__this__>(std::forward(args)...); \
          }
    
    auto ptr = new_anon(interface { ... })(arguments);
    

提交回复
热议问题