Consider that in some library somewhere (which we have no access to change), we have a Counter class:
class Counter {
int count;
public:
Counter() : count(0) { }
void bump() { ++count; }
int getCount() const { return count; }
};
which, by its very nature, is mutable. If it's const, it's pretty worthless.
And in our code, we "use" that Counter. Badly.
#include <string>
#include <iostream>
#include <Counter.hpp>
using std::cout;
using std::endl;
void breakTheHellOutOfCounter(Counter &c) {
// This is OK
c.bump();
// Oh noes!
c = Counter();
}
int main() {
Counter c;
c.bump(); c.bump(); c.bump();
std::cout << "Count was " << c.getCount() << std::endl;
breakTheHellOutOfCounter(c);
std::cout << "Count is now " << c.getCount() << std::endl;
}
Note that breakTheHellOutOfCounter overwrites main's counter with a shiny new one, resetting the count. That's going to cause the caller some grief. (Imagine something a lot more harmful happening, and you'll see where I'm going here.)
I need to be able to bump c (and thus, I need it mutable), but I want breakTheHellOutOfCounter() to fail miserably due to trying to replace c. Is there a way I can change things (other than the Counter class) to make that happen?
(I'm aware that at the lowest levels, this is all but impossible to enforce. What I want is a way to make it hard to do accidentally.)
The cleanest solution I can see to this without modifying counter itself is something like:
#include <string>
#include <iostream>
#include <Counter.hpp>
template <typename T>
struct Unbreakable : public T {
Unbreakable<T>& operator=(const Unbreakable<T>&) = delete;
Unbreakable<T>& operator=(Unbreakable<T>&&) = delete;
template <typename ...Args>
Unbreakable(Args&& ...args) : T(std::forward<Args>(args)...) {}
};
using std::cout;
using std::endl;
void breakTheHellOutOfCounter(Unbreakable<Counter> &c) {
// this is ok
c.bump();
// oh noes!
c = Counter();
}
int main() {
Unbreakable<Counter> c;
c.bump(); c.bump(); c.bump();
std::cout << "Count was " << c.getCount() << std::endl;
breakTheHellOutOfCounter(c);
std::cout << "Count is now " << c.getCount() << std::endl;
}
Which correctly gives an error from your "oh noes" line. (Example uses C++11, but C++98 solution is similar)
That doesn't rule out usage like:
Counter& br = c;
br = Counter();
of course, but without modifying Counter itself I don't think that's avoidable.
The simplest way to do this is to remove the assignment operator from the Counter class. However, since you don't have the ability to change the Counter class, your only real option is to wrap the Counter class in a class with no assignment operator and use that instead.
As Michael Anderson said, you can wrap your counter object in a class that prevents assignment.
class CounterProxy {
Counter& counter;
CounterProxy & operator=(const CounterProxy&);
public:
CounterProxy(Counter& c) : counter(c) {}
void bump() { counter.bump(); }
int getCount() const { return counter.getCount(); }
};
void breakTheHellOutOfCounter(CounterProxy &c) {
// this is ok
c.bump();
// not oh noes!
c = CounterProxy(Counter());
}
int main() {
Counter c;
c.bump(); c.bump(); c.bump();
std::cout << "Count was " << c.getCount() << std::endl;
breakTheHellOutOfCounter(CounterProxy(c));
std::cout << "Count is now " << c.getCount() << std::endl;
}
You can use this method whenever you want to limit the operations that can be performed on an object.
EDIT: You're probably already aware of this and looking for a more elegant solution, but the code might help others.
By allowing bump via a mutable reference, you are giving the function access to mess with the object state. There is nothing special about assignment; it's just a function that mutates the object in some way. It could just as well be a function called CopyStateFromAnotherInstance() instead of operator =().
So the real problem is: How do you allow only certain functions but hide others? By using an interface:
class IBumpable
{
void bump() ...
};
class Counter : IBumpable
{
....
};
void functionThatCannotBreakCounter(IBumpable& counter) { ... }
Related
sorry but I cant understand why 2 times destructor called?
#include <iostream>
#include <thread>
class myClass
{
public:
int integer;
void operator()()
{
std::cout << "class: " << integer << "\t" << std::this_thread::get_id() << std::endl;
}
myClass(int h)
: integer{h}
{
}
~myClass()
{
std::cout << "MyClass by int: " << integer << " destroyed!" << std::endl;
}
};
bool myFunc(int x)
{
myClass tempClass(x);
std::thread one(tempClass);
one.join();
if (x <= 0)
return 0;
else
return myFunc(x - 1);
}
int main()
{
myFunc(10);
return 0;
}
note : I'm just trying in MultiThreads. (training)
and one more problem is that why before joining thread , my class has destroyed!
In the line
std::thread one(tempClass);
a copy of tempClass is created. Later on, both instances of myClass are destroyed.
You can pass tempClass by reference by using std::ref, but then you have to guarantee that tempClass remains valid (e.g. does not go out of scope, is brought in an invalid state by the main thread) throughout the life time of your thread (one).
You can also move tempClass into the other thread. You would still end up with two destructor calls and it would hardly make any difference in your case, but if myClass is difficult to copy, it can make a difference. In that case, you may want to read up on move semantics.
Is there a way to declare a constructor or a destructor in an unnamed class? Consider the following
void f()
{
struct {
// some implementation
} inst1, inst2;
// f implementation - usage of instances
}
Follow up question : The instances are ofcourse constructed (and destroyed) as any stack based object. What gets called? Is it a mangled name automatically assigned by the compiler?
The simplest solution is to put a named struct instance as a member in the unnamed one, and put all of the functionality into the named instance. This is probably the only way that is compatible with C++98.
#include <iostream>
#include <cmath>
int main() {
struct {
struct S {
double a;
int b;
S() : a(sqrt(4)), b(42) { std::cout << "constructed" << std::endl; }
~S() { std::cout << "destructed" << std::endl; }
} s;
} instance1, instance2;
std::cout << "body" << std::endl;
}
Everything that follows requires C++11 value initialization support.
To avoid the nesting, the solution for the construction is easy. You should be using C++11 value initialization for all members. You can initialize them with the result of a lambda call, so you can really execute arbitrarily complex code during the initialization.
#include <iostream>
#include <cmath>
int main() {
struct {
double a { sqrt(4) };
int b { []{
std::cout << "constructed" << std::endl;
return 42; }()
};
} instance1, instance2;
}
You can of course shove all the "constructor" code to a separate member:
int b { [this]{ constructor(); return 42; }() };
void constructor() {
std::cout << "constructed" << std::endl;
}
This still doesn't read all that cleanly, and conflates the initialization of b with other things. You could move the constructor call to a helper class, at the cost of the empty class still taking up a bit of space within the unnamed struct (usually one byte if it's the last member).
#include <iostream>
#include <cmath>
struct Construct {
template <typename T> Construct(T* instance) {
instance->constructor();
}
};
int main() {
struct {
double a { sqrt(4) };
int b { 42 };
Construct c { this };
void constructor() {
std::cout << "constructed" << std::endl;
}
} instance1, instance2;
}
Since the instance of c will use some room, we might as well get explicit about it, and get rid of the helper. The below smells of a C++11 idiom, but is a bit verbose due to the return statement.
struct {
double a { sqrt(4) };
int b { 42 };
char constructor { [this]{
std::cout << "constructed" << std::endl;
return char(0);
}() };
}
To get the destructor, you need the helper to store both the pointer to an instance of the wrapped class, and a function pointer to a function that calls the destructor on the instance. Since we only have access to the unnamed struct's type in the helper's constructor, it's there that we have to generate the code that calls the destructor.
#include <iostream>
#include <cmath>
struct ConstructDestruct {
void * m_instance;
void (*m_destructor)(void*);
template <typename T> ConstructDestruct(T* instance) :
m_instance(instance),
m_destructor(+[](void* obj){ static_cast<T*>(obj)->destructor(); })
{
instance->constructor();
}
~ConstructDestruct() {
m_destructor(m_instance);
}
};
int main() {
struct {
double a { sqrt(4) };
int b { 42 };
ConstructDestruct cd { this };
void constructor() {
std::cout << "constructed" << std::endl;
}
void destructor() {
std::cout << "destructed" << std::endl;
}
} instance1, instance2;
std::cout << "body" << std::endl;
}
Now you're certainly complaining about the redundancy of the data stored in the ConstructDestruct instance. The location where the instance is stored is at a fixed offset from the head of the unnamed struct. You can obtain such offset and wrap it in a type (see here). Thus we can get rid of the instance pointer in the ConstructorDestructor:
#include <iostream>
#include <cmath>
#include <cstddef>
template <std::ptrdiff_t> struct MInt {};
struct ConstructDestruct {
void (*m_destructor)(ConstructDestruct*);
template <typename T, std::ptrdiff_t offset>
ConstructDestruct(T* instance, MInt<offset>) :
m_destructor(+[](ConstructDestruct* self){
reinterpret_cast<T*>(reinterpret_cast<uintptr_t>(self) - offset)->destructor();
})
{
instance->constructor();
}
~ConstructDestruct() {
m_destructor(this);
}
};
#define offset_to(member)\
(MInt<offsetof(std::remove_reference<decltype(*this)>::type, member)>())
int main() {
struct {
double a { sqrt(4) };
int b { 42 };
ConstructDestruct cd { this, offset_to(cd) };
void constructor() {
std::cout << "constructed " << std::hex << (void*)this << std::endl;
}
void destructor() {
std::cout << "destructed " << std::hex << (void*)this << std::endl;
}
} instance1, instance2;
std::cout << "body" << std::endl;
}
Unfortunately, it doesn't seem possible to get rid of the function pointer from within ConstructDestruct. This isn't that bad, though, since its size needs to be non-zero. Whatever is stored immediately after the unnamed struct is likely to be aligned to a multiple of a function pointer size anyway, so there may be no overhead from the sizeof(ConstructDestruct) being larger than 1.
You can not declare a constructor or destructor for an unnamed class because the constructor and destructor names need to match the class name. In your example, the unnamed class is local. It has no linkage so neither mangled name is created.
If you are thinking of C++ names, then any class that has objects has to have a destructor whether you create it explicitly or not. So yes, the compiler knows how to assign a name. Whether that naming convention is any of your business, however, probably not.
Actually, you can create a structure or also a namespace without a name. You still need to have names somewhere because at the time you link all of that, the linker needs some kind of a name to make it all work, although in many cases it will be local names that are resolved immediately at compile time--by the assembler.
One way to know of the names assigned by the compiler is to look at the debug strings and see what corresponds to the different addresses that you're interested in. When you compile with -g then you should get all the necessary debug for your debugger to place your current at the right place with the right "names"... (I've see the namespaces without a name it says " namespace", I'm pretty sure structures use the same trick at a higher level.)
I use std::cout to print the log on console. Since the program is multi-thread, the print result would be disordered, if I use more than one "<<" operate after cout.
For example if one thread executes cout<< "A" << "B" << endl; Another thread might executes cout << "C"; between A and B. The result would be "ACB".
Hence I'm going to write a new class to inherit ostream(which is basic_ostream<char, char_traits<char>> in fact) and add a lock when the cout is initialized, so the print out should follow the proper order.
One option would be to create a class that holds a reference to a stream, but holds a lock throughout it's lifetime. Here's a simple example:
#include <iostream>
#include <mutex>
struct LockedOstream {
std::lock_guard<std::mutex> lg_;
std::ostream& os_;
LockedOstream(std::mutex& m, std::ostream& os)
: lg_{m}
, os_{os}
{ }
std::ostream& stream() const { return os_; }
};
int main()
{
std::mutex m;
LockedOstream(m, std::cout).stream() << "foo " << "bar\n";
// ^ locked now ^ unlocked now
}
This works as long as all the printing that forms a single "unit" of output all occurs in the same statement.
Edit: Actually, the inheritance version is a lot nicer than I originally expected:
#include <iostream>
#include <mutex>
class LockedOstream : public std::ostream {
static std::mutex& getCoutMutex()
// use a Meyers' singleton for the cout mutex to keep this header-only
{
static std::mutex m;
return m;
}
std::lock_guard<std::mutex> lg_;
public:
// Generic constructor
// You need to pass the right mutex to match the stream you want
LockedOstream(std::mutex& m, std::ostream& os)
: std::ostream(os.rdbuf())
, lg_{m}
{ }
// Cout specific constructor
// Uses a mutex singleton specific for cout
LockedOstream()
: LockedOstream(getCoutMutex(), std::cout)
{ }
};
int main()
{
LockedOstream() << "foo " << "bar\n";
// ^ locked now ^ unlocked now
}
As an aside:
using namespace std; is widely considered bad practice, and
I'm not a big fan of std::endl
either
(though the latter is sometimes contentious, but at least it's a good idea to know and make an informed choice).
You can define your own function
template<typename... Ts>
void locked_print(std::ostream& stream, Ts&&... ts)
{
static std::mutex mtx;
std::lock_guard<std::mutex> guard(mtx);
(stream << ... << std::forward<Ts>(ts));
}
And when you want to be sure it's exclusive, you can call it like locked_print(std::cout, 1, 2, "bar");
Since outstream << x1 << x2 << ... are multiple function calls, there is no way you can do that internally, besides locking everything until destruction of that same outstream.
You can just force your constraint when you call it:
{
std::lock_guard<std::mutex> guard(global_mutex);
// your print here
}
Is there a way to declare a constructor or a destructor in an unnamed class? Consider the following
void f()
{
struct {
// some implementation
} inst1, inst2;
// f implementation - usage of instances
}
Follow up question : The instances are ofcourse constructed (and destroyed) as any stack based object. What gets called? Is it a mangled name automatically assigned by the compiler?
The simplest solution is to put a named struct instance as a member in the unnamed one, and put all of the functionality into the named instance. This is probably the only way that is compatible with C++98.
#include <iostream>
#include <cmath>
int main() {
struct {
struct S {
double a;
int b;
S() : a(sqrt(4)), b(42) { std::cout << "constructed" << std::endl; }
~S() { std::cout << "destructed" << std::endl; }
} s;
} instance1, instance2;
std::cout << "body" << std::endl;
}
Everything that follows requires C++11 value initialization support.
To avoid the nesting, the solution for the construction is easy. You should be using C++11 value initialization for all members. You can initialize them with the result of a lambda call, so you can really execute arbitrarily complex code during the initialization.
#include <iostream>
#include <cmath>
int main() {
struct {
double a { sqrt(4) };
int b { []{
std::cout << "constructed" << std::endl;
return 42; }()
};
} instance1, instance2;
}
You can of course shove all the "constructor" code to a separate member:
int b { [this]{ constructor(); return 42; }() };
void constructor() {
std::cout << "constructed" << std::endl;
}
This still doesn't read all that cleanly, and conflates the initialization of b with other things. You could move the constructor call to a helper class, at the cost of the empty class still taking up a bit of space within the unnamed struct (usually one byte if it's the last member).
#include <iostream>
#include <cmath>
struct Construct {
template <typename T> Construct(T* instance) {
instance->constructor();
}
};
int main() {
struct {
double a { sqrt(4) };
int b { 42 };
Construct c { this };
void constructor() {
std::cout << "constructed" << std::endl;
}
} instance1, instance2;
}
Since the instance of c will use some room, we might as well get explicit about it, and get rid of the helper. The below smells of a C++11 idiom, but is a bit verbose due to the return statement.
struct {
double a { sqrt(4) };
int b { 42 };
char constructor { [this]{
std::cout << "constructed" << std::endl;
return char(0);
}() };
}
To get the destructor, you need the helper to store both the pointer to an instance of the wrapped class, and a function pointer to a function that calls the destructor on the instance. Since we only have access to the unnamed struct's type in the helper's constructor, it's there that we have to generate the code that calls the destructor.
#include <iostream>
#include <cmath>
struct ConstructDestruct {
void * m_instance;
void (*m_destructor)(void*);
template <typename T> ConstructDestruct(T* instance) :
m_instance(instance),
m_destructor(+[](void* obj){ static_cast<T*>(obj)->destructor(); })
{
instance->constructor();
}
~ConstructDestruct() {
m_destructor(m_instance);
}
};
int main() {
struct {
double a { sqrt(4) };
int b { 42 };
ConstructDestruct cd { this };
void constructor() {
std::cout << "constructed" << std::endl;
}
void destructor() {
std::cout << "destructed" << std::endl;
}
} instance1, instance2;
std::cout << "body" << std::endl;
}
Now you're certainly complaining about the redundancy of the data stored in the ConstructDestruct instance. The location where the instance is stored is at a fixed offset from the head of the unnamed struct. You can obtain such offset and wrap it in a type (see here). Thus we can get rid of the instance pointer in the ConstructorDestructor:
#include <iostream>
#include <cmath>
#include <cstddef>
template <std::ptrdiff_t> struct MInt {};
struct ConstructDestruct {
void (*m_destructor)(ConstructDestruct*);
template <typename T, std::ptrdiff_t offset>
ConstructDestruct(T* instance, MInt<offset>) :
m_destructor(+[](ConstructDestruct* self){
reinterpret_cast<T*>(reinterpret_cast<uintptr_t>(self) - offset)->destructor();
})
{
instance->constructor();
}
~ConstructDestruct() {
m_destructor(this);
}
};
#define offset_to(member)\
(MInt<offsetof(std::remove_reference<decltype(*this)>::type, member)>())
int main() {
struct {
double a { sqrt(4) };
int b { 42 };
ConstructDestruct cd { this, offset_to(cd) };
void constructor() {
std::cout << "constructed " << std::hex << (void*)this << std::endl;
}
void destructor() {
std::cout << "destructed " << std::hex << (void*)this << std::endl;
}
} instance1, instance2;
std::cout << "body" << std::endl;
}
Unfortunately, it doesn't seem possible to get rid of the function pointer from within ConstructDestruct. This isn't that bad, though, since its size needs to be non-zero. Whatever is stored immediately after the unnamed struct is likely to be aligned to a multiple of a function pointer size anyway, so there may be no overhead from the sizeof(ConstructDestruct) being larger than 1.
You can not declare a constructor or destructor for an unnamed class because the constructor and destructor names need to match the class name. In your example, the unnamed class is local. It has no linkage so neither mangled name is created.
If you are thinking of C++ names, then any class that has objects has to have a destructor whether you create it explicitly or not. So yes, the compiler knows how to assign a name. Whether that naming convention is any of your business, however, probably not.
Actually, you can create a structure or also a namespace without a name. You still need to have names somewhere because at the time you link all of that, the linker needs some kind of a name to make it all work, although in many cases it will be local names that are resolved immediately at compile time--by the assembler.
One way to know of the names assigned by the compiler is to look at the debug strings and see what corresponds to the different addresses that you're interested in. When you compile with -g then you should get all the necessary debug for your debugger to place your current at the right place with the right "names"... (I've see the namespaces without a name it says " namespace", I'm pretty sure structures use the same trick at a higher level.)
I'm trying to make a class runner (run a class at a fixed time freq), which runs a class in another thread, and can be controlled (like pause, resume, stop) from main thread.
So I want to take advantage of C++11's Functor and other features. But I have a strange problem, the Functor's destructor passed into Runner has been called twice.
#include <iostream>
#include <chrono>
#include <thread>
using namespace std;
class Runner {
public:
typedef function<bool()> fn_t;
Runner(fn_t &&fn) : fn_(move(fn)), thread_(Thread, ref(*this)) {
cout << "Runner" << endl;
}
~Runner() {
cout << "~Runner" << endl;
thread_.join();
}
private:
fn_t fn_;
thread thread_;
static void Thread(Runner &runner) {
while (runner.fn_()) {
cout << "Running" << endl;
this_thread::sleep_for(chrono::milliumseconds(1));
}
}
};
class Fn {
public:
Fn() : count(0) {
cout << "Fn" << endl;
}
~Fn() {
cout << "~Fn" << endl;
}
bool operator()() {
return (++count < 5);
}
private:
int count;
};
int main (int argc, char const* argv[])
{
Fn fn;
Runner runner(move(fn));
return 0;
}
outpus:
Fn
Runner
~Fn
~Runner
Running
Running
Running
Running
Running
~Fn
~Fn
and if I change
Fn fn;
Runner runner(move(fn));
to
Runner runner(Fn());
the program outpus nothing and stalls. I have tried to disable compiling optimization, nothing changes. Any explanation?
How can I fix this or do the samething in other method? Should I implement this class like std::async / std::thread?
Update to Runner runner(Fn())
This statement was interrupted as a function declaration.
Runner runner((Fn())) solved problem.
Thanks for all comments and answers. After look into rvalue, seems I have misunderstand the meaning of rvalue reference from ground 0. I will try some other ways.
Final Solution for this problem
#include <iostream>
#include <chrono>
#include <thread>
#include <vector>
using namespace std;
template<typename T, typename... Args>
class Runner {
public:
Runner(Args&&... args) :
t(forward<Args>(args)...),
thread_(Thread, ref(*this)) {
cout << "Runner" << endl;
}
~Runner() {
cout << "~Runner" << endl;
thread_.join();
}
private:
T t;
thread thread_;
static void Thread(Runner &runner) {
while (runner.t()) {
cout << "Running" << endl;
this_thread::sleep_for(chrono::milliseconds(100));
}
}
};
class Fn {
public:
Fn() : count(0) {
cout << "Fn" << endl;
}
~Fn() {
cout << "~Fn" << endl;
}
bool operator()() {
return (count++ < 5);
}
private:
int count;
};
int main (int argc, char const* argv[])
{
//vector<Fn> fns;
//fns.emplace_back(Fn());
Runner<Fn> runner;
return 0;
}
outpus:
Fn
Runner
~Runner
Running
Running
Running
Running
Running
~Fn
Use std::move:
Runner(fn_t &&fn) : fn_(std::move(fn)), thread_(Thread, ref(*this)) {
/*....*/
}
You need to explicitly use std::move, otherwise it will be treated as a const reference. You could also use std::forward:
Runner(fn_t &&fn) : fn_(std::forward<fn_t>(fn)), thread_(Thread, ref(*this)) {
/*....*/
}
First of all, you shouldn't be taking r-value reference arguments for the most part, except in your own move constructors. As you have it, there is no way to pass l-values of std::function<bool()> into the constructor of Runner.
int main()
{
Fn fn;
std::function<bool()> func(fn);
Runner runner(func); // this is illegal
}
Maybe I'm just not creative enough, but I can't imagine any valid reason which you would want to prevent such a thing.
You should let std::function take care of its own copying/moving. When you need a copy of an object, take your parameter by value. If the function is passed an r-value, then it will be move constructed. If it is passed an l-value, then it will be copy constructed. Then, in your Runner constructor, you can move the value into the member object, as fontanini showed.
None of this is guaranteed to reduce destructor calls though, because when you move an object, you're still creating a second object, and will have to destroy a second object. In order to see fewer destructions, copy elision would have to happen, which actually does avoid the creation of multiple objects. But unlike moving, that's an implementation issue that's not guaranteed to come into effect in all the situations where you would hope.