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

Or just put

can i do something like

class A { public: virtual void foo() = 0; }; class B { public: A *a; b(){ a = new A() { void foo() {printf("hello");} } }; 
+4
source share
4 answers

No, C ++ does not have anonymous classes such as Java.

You can define local classes, for example:

 class B { public: A *a; b(){ struct my_little_class : public A { void foo() {printf("hello");} }; a = new my_little_class(); } }; 

Or maybe just a nested class:

 class B { private: struct my_little_class : public A { void foo() {printf("hello");} }; public: A *a; b(){ a = new my_little_class(); } }; 

In C ++ 03, local classes have some limitations (for example, they cannot be used as template parameters) that were removed in C ++ 11.

In Java, anonymous classes are sometimes used to execute other languages ​​with anonymous functions, for example, when creating an anonymous Runnable implementation. C ++ 11 has anonymous functions (also known as lambdas), so this may be an option if this is what you are trying to achieve.

+6
source

The same answer as for the rest, but if you want to imitate this behavior, you can (I do not recommend it):

  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, because you cannot have a static member in this new class, and that it uses the Gcc / g ++ operator expression: Statement-Exprs

The solution for the static member will be as follows: imagine that we want the static int to increase in several situations in our previous tmp class, it 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; }); 

As a result, all new pointers specified by getDefault () will refer to the same integer. Note that with C ++ 11 auto, you can access all public members as expected and use the hierarchy to create a child of the specified type:

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

Update: More modern C ++ (14-17) without extensions will be

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

No. Everything that should be in C ++ must be defined before using it. In your case, since you want to override A::foo() , you should get a new class, and then B can instantiate this class, for example:

 class A { public: virtual void foo() = 0; }; class A1 : public A { public: void foo() { printf("hello"); } }; class B { public: A *a; B() { a = new A1(); } }; 
+1
source

No.

But this idiom is common in Java when passing callbacks to the API. If this is what you want (register callbacks for the API), you can use signals, for example, implemented on Boost.Signals or libsig ++ (the best way in this case).

Also, closer in syntax to what you want, the new C ++ specification (C ++ 11, supported by the latest compilers) also allows you to use lambda functions:

 template<class F> void func(F callable) { callable(); // Callable is an object that can be called as a function. } void a() { method([]() { printf("hello"); }); // This anonymous function was defined here... } 

If you really want to define a new class on the fly, you cannot make it inline, but you can do it “a little higher”:

 class A { public: virtual void foo() = 0; }; class B { public: A *a; void b(){ class MyImplementation: public A { public: void foo() { printf("hello"); } }; a = new MyImplementation(); } }; 

A class may be anonymous, but you can only create an object on the stack (i.e. you cannot use new in an anonymous class, and it will be freed from returning a function ):

 void function_that_uses_but_does_not_stores_A(A* obj); void function(){ class : public A { public: void foo() { printf("hello"); } } obj; function_that_uses_but_does_not_stores_A(&obj); }; 
+1
source

Source: https://habr.com/ru/post/1384022/


All Articles