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() { void foo() {printf("hello");}
}
};
No, C++ doesn't have anonymous classes like Java's.
You can define local classes, like this:
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 can't be used as template parameters) that were lifted in C++11.
In Java, anonymous classes are sometimes used to do what other languages do with anonymous functions like, for example, when you create an anonymous implementation of Runnable
. C++11 has anonymous functions (also known as lambdas), so that could be an option if this is what you're trying to achieve.
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<decltype(args)>(args)...); \
}
auto ptr = new_anon(interface { ... })(arguments);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With