Does std::future in c++ support polymorphism?
So, if to store child_class in future<parent_class>, can I after get it after by dynamic_cast<child_class>?
Providing you use a reference or a pointer (probably obvious since it'll fail to compile otherwise)... Yes.
#include <iostream>
#include <future>
using namespace std;
struct Parent {
virtual void a() { cout << "I am parent"; }
};
struct Child : Parent {
virtual void a() { cout << "I am child"; }
};
Child g_c; //just some global for the purposes of the example
int main() {
std::future<Parent&> p = async(launch::async, []() -> Parent& { return g_c; });
auto c = dynamic_cast<Child&>(p.get());
c.a();
return 0;
}
code result here: http://ideone.com/4Qmjvc
Related
I want to store 6 pointers to objects. But the Pointers can be in any order and point to different instances of (12) subclasses of one superclass, so they are possibly all of different types.
Arrays and such don't work, because the superclass is virtual.
Vectors and Tuples don't work, because the datatypes are of no specific order and are not known at compile time.
Im fairly new to C++ and I'm running out of Ideas.
Here some code to elaborate the problem:
baseclass{
getfoobar()=0;
}
subclass1{
getfoobar(){...}
}
subclass2{
getfoobar(){...}
}
---
#include <otherclasses.h>
memoryclass{
baseclass mem[6];
}
is basically what im trying.
You CAN create a vector of superclass pointers. It will achieve what you want, as it will call the overwritten function. This is of course assuming you are talking about inheritance, like:
#include <vector>
using type = ????;
class A {
virtual type foo() = 0;
}
class B : A {
type foo() override { ... }
}
class C : A {
type foo() override { ... }
}
int main(){
std::vector<A*> arr;
arr.push_back(new B);
arr.push_back(new C);
}
Now if I misunderstood and this doesn't work for some reason (i.e. they just share the function and are not actually related classes), you can do something like this, but it is not very nice:
#include <concepts>
#include <vector>
#include <functional>
using type = ?????;
template <class T> requires requires(T t){
{ t.foo() } -> std::same_as<type>;
}
std::function<type()> getFunction(T* t){
return [t](){ return t->foo(); };
}
int main(){
std::vector<std::function<type()>> arr;
arr.push_back(getFunction(new B));
arr.push_back(getFunction(new C));
}
I don't recommend this over the first option unless you have very good reason to do this.
Note: Since you didn't specify return type I winged it with ?????
Also: In the second you can replace template<class T> requires ... std::function<type()>, with just template<class T> std::function<type()>, if the compiler doesn't like #include <concepts>
You can try std::set<Superclass*>. Use pointers to your base superclass instead pointers to particular subclasses.
Actually I used std::shared_ptr<> smart pointer template to avoid raw memory management.
Example code:
#include <cstdlib>
#include <string>
#include <sstream>
#include <set>
#include <memory>
#include <iostream>
class baseclass {
public:
virtual std::string getfoobar() = 0;
};
typedef std::shared_ptr<baseclass> baseclass_ptr;
class subclass1 : public baseclass{
public:
std::string getfoobar() override {
return "from subclass1";
}
};
class subclass2 : public baseclass{
public:
std::string getfoobar() override {
return "from subclass2";
}
};
int main(int argc, char** argv) {
// Use current time as seed for random generator
std::srand(static_cast<unsigned>(std::time(nullptr)));
std::set<baseclass_ptr> container;
// Randomly generate number of elements
const int random_count = std::rand() % 10 + 1;
for (int i = 0; i < random_count; ++i) {
// Randomly create subclass1 or subclass2
if (std::rand() % 2) {
container.insert(std::make_shared<subclass1>());
}
else {
container.insert(std::make_shared<subclass2>());
}
}
// Iterate resulting container
std::cout << "size = " << container.size() << std::endl;
for (auto iterator : container) {
std::cout << "getfoobar(): " << iterator->getfoobar() << std::endl;
}
return 0;
}
I have a bit of trouble understanding a std::bind call.
In the following example:
#include <functional>
#include <iostream>
#include <memory>
class Notifier
{
public:
Notifier(std::function<void(Notifier&)> on_notify)
:on_notify_(on_notify)
{ }
void notify()
{
if (on_notify_)
on_notify_(*this);
}
std::function<void(Notifier&)> on_notify_;
};
struct Manager
{
Manager()
{
n_ = std::make_unique<Notifier>(std::bind(&Manager::trigger, this));
}
void trigger()
{
std::cout << "notified" << std::endl;
}
std::unique_ptr<Notifier> n_;
};
int main()
{
Manager s;
s.n_->notify();
}
I don't understand how on_notify_(*this); calls back the functor with a Notifier& parameter, but the functor created by bind doesn't specify it.
The calls result correctly to the void notify() method, but I don't understand what exactly will be the functor created by bind to result in this.
If I were to write a lambda instead, I would need to specify the parameter, otherwise it would compile.
What kind of operation does bind here behind my back? :-)
std::bind basically ignores the invalid given argument according to this.
If some of the arguments that are supplied in the call to g() are not matched by any placeholders stored in g, the unused arguments are evaluated and discarded.
It might surprise you that when even more absurd arguments are provided, the binded functor can still successfully reach Manager::trigger() as follows:
#include <functional>
#include <iostream>
#include <memory>
// Some classes that have nothing to do with on_notify_
class AAA {};
class BBB {};
class Notifier
{
public:
Notifier(std::function<void(AAA&, BBB&)> on_notify)
:on_notify_(on_notify)
{ }
void notify()
{
if (on_notify_)
{
// Arguments not matching.
AAA a{};
BBB b{};
// Invoke with them.
on_notify_(a, b);
}
}
std::function<void(AAA&, BBB&)> on_notify_;
};
struct Manager
{
Manager()
{
n_ = std::make_unique<Notifier>(std::bind(&Manager::trigger, this));
}
void trigger()
{
std::cout << "it's also notified!" << std::endl;
}
std::unique_ptr<Notifier> n_;
};
int main()
{
Manager s;
s.n_->notify();
}
Live demo is here.
How can such a code work correctly when the IWindow pointer clearly has an address to a ISheet class which has no method Say?
#include <iostream>
using namespace std;
class IWindow
{
private:
int p;
double f;
public:
void Say() { cout << "Say in IWindow"; }
};
class ISheet
{
public:
void foo() { cout << "ISheet::foo"; }
};
int main()
{
ISheet *sh = new ISheet();
int ptr = (int)sh;
IWindow *w = (IWindow*)ptr;
w->Say();
sh->foo();
return 0;
}
When compiled in Visual Studio 2015 it runs and executes with no problems, but I was expecting to get an error on line w->Say(). How is this possible?
It works by the grace of the almighty Undefined Behavior. Your functions don't try to access any data members of the containing class, they just write something to std::cout, which anyone can do.
What you've effectively done is
#include <iostream>
void IWindow_Say(void*)
{
std::cout << "Say in IWindow";
}
int main()
{
IWindow_Say(0xdeadbeef); // good luck with that pointer
}
You never used the pointer (which became this in your original example) so no side-effects were observed.
I am developing a C++ tool that should run transparent to main program. That is: if user simply links the tool to his program the tool will be activated. For that I need to invoke two functions, function a(), before main() gets control and function b() after main() finishes.
I can easily do the first by declaring a global variable in my program and have it initialize by return code of a(). i.e
int v = a() ;
but I cannot find a way to call b() after main() finishes?
Does any one can think of a way to do this?
The tool runs on windows, but I'd rather not use any OS specific calls.
Thank you, George
Use RAII, with a and b called in constructor/destructor.
class MyObj {
MyObj()
{
a();
};
~MyObj()
{
b();
};
};
Then just have an instance of MyObj outside the scope of main()
MyObj obj;
main()
{
...
}
Some things to note.
This is bog-standard C++ and will work on any platform
You can use this without changing ANY existing source code, simply by having your instance of MyObj in a separate compilation unit.
While it will run before and after main(), any other objects constructed outside main will also run at this time. And you have little control of the order
of your object's construction/destruction, among those others.
SOLUTION IN C:
have a look at atexit:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void bye(void)
{
printf("That was all, folks\n");
}
int main(void)
{
long a;
int i;
a = sysconf(_SC_ATEXIT_MAX);
printf("ATEXIT_MAX = %ld\n", a);
i = atexit(bye);
if (i != 0) {
fprintf(stderr, "cannot set exit function\n");
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}
http://linux.die.net/man/3/atexit
this still implies however that you have access to your main and you can add the atexit call. If you have no access to the main and you cannot add this function call I do not think there is any option.
EDIT:
SOLUTION IN C++:
as sudgested there is a c++ equivalent from std. I simply paste in here an example which i copied from the link available just below the code:
#include <iostream>
#include <cstdlib>
void atexit_handler_1()
{
std::cout << "at exit #1\n";
}
void atexit_handler_2()
{
std::cout << "at exit #2\n";
}
int main()
{
const int result_1 = std::atexit(atexit_handler_1);
const int result_2 = std::atexit(atexit_handler_2);
if ((result_1 != 0) or (result_2 != 0)) {
std::cerr << "Registration failed\n";
return EXIT_FAILURE;
}
std::cout << "returning from main\n";
return EXIT_SUCCESS;
}
http://en.cppreference.com/w/cpp/utility/program/atexit
Isn't any global variable constructed before main and destructed afterward? I made a test struct whose constructor is called before main and the destructor afterward.
#include <iostream>
struct Test
{
Test() { std::cout << "Before main..." << std::endl; }
~Test() { std::cout << "After main..." << std::endl; }
};
Test test;
int main()
{
std::cout << "Returning now..." << std::endl;
return 0;
}
If you're happy to stick with a single compiler and non-standard C/C++, then GCC's __attribute__((constructor)) and __attribute__((destructor)) might be of use:
#include <stdio.h>
void __attribute__((constructor)) ctor()
{
printf("Before main()\n");
}
void __attribute__((destructor)) dtor()
{
printf("After main()\n");
}
int main()
{
printf("main()\n");
return 0;
}
Result:
Before main()
main()
After main()
Alternatively to the destructor, you can use atexit() in a similar manner - in C++, you do not need to have access to main() to register atexit there. You can do that as well it in your a() - for example:
void b(void) {
std::cout << "Exiting.\n";
}
int a(void) {
std::cout << "Starting.\n";
atexit(b);
return 0;
}
// global in your module
int i = a();
That being said, I'd also prefer the global C++ class object, which will call the b() stuff in its destructor.
#include <iostream>
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <boost/enable_shared_from_this.hpp>
class A: public boost::enable_shared_from_this<A>
{
typedef boost::function<int()> GET;
public:
A()
{
std::cout << "A::A() " << this << std::endl;
}
~A()
{
std::cout << "A::~A()" << this <<std::endl;
}
void set()
{
myget=boost::bind(&A::get, shared_from_this());
}
Here is the problem: it will not be released when I bind it with with shared_from_this(). But if I bind it with this (boost::bind(&A::get, this)), the instance will be released.
int getI()
{
myget();
}
inline int get()
{
return 1;
}
private:
GET myget;
};
void test()
{
boost::shared_ptr<A> a(new A);
a->set();
a->getI();
}
int main()
{
test();
return 0;
}
My question is: why the instance of A is never released even if the program have been shut down?
The problem is that the myget variable prevents the destructor from ever running.
So you can't even do
~A() {
std::cout << "A::~A()" << this << std::endl;
myget = {};
}
This is what weak-pointers have been invented for. In this particular case though, you could simply use this as there is no way that myget can be accessed after the lifetime of A