good article on threads... I have a question

G

grahamo

Hi,

I realise that c++ knows nothing about threads however my question is
related to an (excellent) article I was reading about threads and C++.
For all intents and purposes we can forget the sample at hand is
concerned about threads, it could be related to widgets for the
purpose of this question (that's so I don't get flamed and told to go
to comp.programming.threads :)


However while discussing how to define a template class to be used for
synchronisation, the author defines it thus;


template <class T> class StrictLock {
T& obj_;
StrictLock(); // disable default constructor
StrictLock(const StrictLock&); // disable copy constructor
StrictLock& operator=(const StrictLock&); // disable assignment
void* operator new(std::size_t); // disable heap allocation
void* operator new[](std::size_t);
void operator delete(void*);
void operator delete[](void*);
StrictLock* operator&(); // disable address taking
public:
StrictLock(T& obj) : obj_(obj) {
obj.AcquireMutex();
}
~StrictLock() {
obj_.ReleaseMutex();
}
};


He then goes on to say how these definitions prevent copy
construction, construction on the heap, etc. etc. That's fine and
dandy. However he then mentions;

"You cannot allocate a StrictLock on the heap. However, you still can
put StrictLocks on the heap if they're members of a class.


class Wrapper {
Lock memberLock_;
...
};
Wrapper* pW = new Wrapper; // ok "



How is this so? Given the declaration above and the code he cite, how
can StrictLocks be put on the heap if they're members of a class? I
trust this dude based on everything else he's said in the article so
the misunderstanding is a C++ one on my part. If anybody can enlighten
me I'd be very grateful.

Cheers

GrahamO

BTW, the threads article can be found at;

http://www.informit.com/articles/article.asp?p=25298
 
V

Victor Bazarov

grahamo said:
I realise that c++ knows nothing about threads however my question is
related to an (excellent) article I was reading about threads and C++.
For all intents and purposes we can forget the sample at hand is
concerned about threads, it could be related to widgets for the
purpose of this question (that's so I don't get flamed and told to go
to comp.programming.threads :)


However while discussing how to define a template class to be used for
synchronisation, the author defines it thus;


template <class T> class StrictLock {
T& obj_;
StrictLock(); // disable default constructor
StrictLock(const StrictLock&); // disable copy constructor
StrictLock& operator=(const StrictLock&); // disable assignment
void* operator new(std::size_t); // disable heap allocation
void* operator new[](std::size_t);
void operator delete(void*);
void operator delete[](void*);
StrictLock* operator&(); // disable address taking
public:
StrictLock(T& obj) : obj_(obj) {
obj.AcquireMutex();
}
~StrictLock() {
obj_.ReleaseMutex();
}
};


He then goes on to say how these definitions prevent copy
construction, construction on the heap, etc. etc. That's fine and
dandy. However he then mentions;

"You cannot allocate a StrictLock on the heap. However, you still can
put StrictLocks on the heap if they're members of a class.


class Wrapper {
Lock memberLock_;
...
};
Wrapper* pW = new Wrapper; // ok "



How is this so? Given the declaration above and the code he cite, how
can StrictLocks be put on the heap if they're members of a class? I
trust this dude based on everything else he's said in the article so
the misunderstanding is a C++ one on my part. If anybody can enlighten
me I'd be very grateful.

Since 'operator new' is overloaded for 'Lock' and made private, you can't
use 'new Lock' because it will attempt to call 'Lock::eek:perator new', which
is inaccessible. However, if a Lock is a subobject of another object,
then that object's 'operator new' is used to allocate memory (or the
global one, if no overloaded 'new' exists) and the fact that 'Lock's 'new'
is private doesn't matter any more.

V
 
D

Dietmar Kuehl

grahamo said:
template <class T> class StrictLock {
T& obj_;
StrictLock(); // disable default constructor
StrictLock(const StrictLock&); // disable copy constructor
StrictLock& operator=(const StrictLock&); // disable assignment
void* operator new(std::size_t); // disable heap allocation
void* operator new[](std::size_t);
void operator delete(void*);
void operator delete[](void*);
StrictLock* operator&(); // disable address taking
public:
StrictLock(T& obj) : obj_(obj) {
obj.AcquireMutex();
}
~StrictLock() {
obj_.ReleaseMutex();
}
};

The above declaration makes many things private but still has a
public constructor (actually, it would not be necessary to make
the default constructor private as generation of this constructor
is inhibited by the presence of another constructor).
"You cannot allocate a StrictLock on the heap. However, you still can
put StrictLocks on the heap if they're members of a class.


class Wrapper {
Lock memberLock_;
...
};
Wrapper* pW = new Wrapper; // ok "

How is this so?

Well, you can obviously make the 'Lock' class a member of 'Wrapper'.
For the construction of a 'Wrapper' object you would need to
initialize this member properly which is easily done like this:

Wrapper::Wrapper(): memberLock(someObject) {}

Nothing prevent construction of such an object on the heap which
effectively causes the lock to reside on the heap - although nested
within another object.

However, I wouldn't consider this to be a problem: the mechanisms
in C++ prevent accidental misuses but not deliberate misuses.
Somebody put it concisely like this: "C++ defends against Murphy,
not against Machiavelli".
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top