By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
454,925 Members | 1,134 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 454,925 IT Pros & Developers. It's quick & easy.

disabling temporaries for a specific class

P: n/a
Hi,

I've been doing a reoccuring programming error. I'm using a Guard
class (like as in a mutex guard).
The Guard is doing a glBindTexture(new texture) in the constructor,
and then a unbinding BindTexture (original texture) in the
destructor. (see code at the end of this message).

Example:
{
Guard g(x); // constructor called, bind
int i;
// some code
} // destructor of g called, unbind

But sometimes I make a mistake and do:
{
Guard(x); //constructor, destructor calls
// BUG, NOT BOUND
..
}

Is there a way to enforce no temporaries for an object, using any
combination of techniques or consts, or special function calls?

Thanks in advance!
Chris

class BindGuard
{
public:
BindGuard(GlTexture2D * t)
{
int i;
glGetIntegerv(GL_TEXTURE_BINDING_2D, &i);
_oldTex = i;
if (_oldTex != t->texId())
{
glBindTexture(GL_TEXTURE_2D, t->texId());
}
}
~BindGuard()
{
if (_oldTex != _t->texId())
{
glBindTexture(GL_TEXTURE_2D, _oldTex);
}
}
private:
GlTexture2D * _t;
GLuint _oldTex;
};

Mar 16 '07 #1
Share this Question
Share on Google+
7 Replies


P: n/a
in******@gmail.com wrote:
Hi,

I've been doing a reoccuring programming error. I'm using a Guard
class (like as in a mutex guard).
The Guard is doing a glBindTexture(new texture) in the constructor,
and then a unbinding BindTexture (original texture) in the
destructor. (see code at the end of this message).

Example:
{
Guard g(x); // constructor called, bind
int i;
// some code
} // destructor of g called, unbind

But sometimes I make a mistake and do:
{
Guard(x); //constructor, destructor calls
// BUG, NOT BOUND
..
}

Is there a way to enforce no temporaries for an object, using any
combination of techniques or consts, or special function calls?
....

Not that I know of.

One suggestion is to not allow access to x other than through the guard.
i.e.

{
Guard g(x);

g.DoStuffToX( blah );
}

or even

{
Guard(x).DoStuffToX( blah );
}

That would mean you would need to stop pushing around raw ogl pointers.

Mar 16 '07 #2

P: n/a
Gianni Mariani wrote:
in******@gmail.com wrote:
>Hi,

I've been doing a reoccuring programming error. I'm using a Guard
class (like as in a mutex guard).
The Guard is doing a glBindTexture(new texture) in the constructor,
and then a unbinding BindTexture (original texture) in the
destructor. (see code at the end of this message).

Example:
{
Guard g(x); // constructor called, bind
int i;
// some code
} // destructor of g called, unbind

But sometimes I make a mistake and do:
{
Guard(x); //constructor, destructor calls
// BUG, NOT BOUND
..
}

Is there a way to enforce no temporaries for an object, using any
combination of techniques or consts, or special function calls?
...

Not that I know of.

One suggestion is to not allow access to x other than through the guard.
i.e.

{
Guard g(x);

g.DoStuffToX( blah );
}

or even

{
Guard(x).DoStuffToX( blah );
}

That would mean you would need to stop pushing around raw ogl pointers.
Yeah, using the Guard as a proxy as Gianni suggested is the best way.
However, you are not guaranteed to have the destructor to be called at
any particular time. I.e. It will be destroyed between the last time
it is used to the end of the enclosing scope. When that will happen
depends on the compiler. To ensure that it is destroyed when you
expect, you must enclose the section with braces and not have other
things in it, just as Gianni's example shows.
Adrian

--
__________________________________________________ ___________________
\/Adrian_Hawryluk BSc. - Specialties: UML, OOPD, Real-Time Systems\/
\ My newsgroup writings are licensed under the Creative Commons /
\ Attribution-Noncommercial-Share Alike 3.0 License /
\_____[http://creativecommons.org/licenses/...sa/3.0/]_____/
\/______[blog:__http://adrians-musings.blogspot.com/]______\/
Mar 17 '07 #3

P: n/a
Adrian Hawryluk wrote:
Gianni Mariani wrote:
....
>One suggestion is to not allow access to x other than through the
guard. i.e.

{
Guard g(x);

g.DoStuffToX( blah );
}

or even

{
Guard(x).DoStuffToX( blah );
}

That would mean you would need to stop pushing around raw ogl pointers.
Yeah, using the Guard as a proxy as Gianni suggested is the best way.
However, you are not guaranteed to have the destructor to be called at
any particular time. I.e. It will be destroyed between the last time
it is used to the end of the enclosing scope. When that will happen
depends on the compiler. To ensure that it is destroyed when you
expect, you must enclose the section with braces and not have other
things in it, just as Gianni's example shows.
The compiler would be non compliant if it deletes the temporary before
calling DoStuffToX in either case.
Mar 17 '07 #4

P: n/a
On Mar 17, 12:51 am, Gianni Mariani <gi3nos...@mariani.wswrote:
Adrian Hawryluk wrote:
Gianni Mariani wrote:
...
One suggestion is to not allow access to x other than through the
guard. i.e.
{
Guard g(x);
g.DoStuffToX( blah );
}
or even
{
Guard(x).DoStuffToX( blah );
}
That would mean you would need to stop pushing around raw ogl pointers.
Yeah, using the Guard as a proxy as Gianni suggested is the best way.
However, you are not guaranteed to have the destructor to be called at
any particular time. I.e. It will be destroyed between the last time
it is used to the end of the enclosing scope. When that will happen
depends on the compiler. To ensure that it is destroyed when you
expect, you must enclose the section with braces and not have other
things in it, just as Gianni's example shows.

The compiler would be non compliant if it deletes the temporary before
calling DoStuffToX in either case.
I made a solution, thanks for your input guys!
#include <iostream>
#include <assert.h>

class NonTemp
{
public:
NonTemp(NonTemp & tmp)
{
assert(&tmp == this);
}
};

class Guard : public NonTemp
{
public:
Guard(NonTemp & t, int i) : NonTemp(t), _i(i)
{
std::cout << "interesting Non Temporary hack my Chris
in******@gmail.com" << std::endl;
}
~Guard()
{
std::cout << "dest" << std::endl;
}
private:
int _i;
};
int main()
{
Guard g(g, 1);
std::cout << "middle" << std::endl;

// impossible to make a temp!
}



Mar 17 '07 #5

P: n/a
in******@gmail.com wrote:
....
I made a solution, thanks for your input guys!
#include <iostream>
#include <assert.h>

class NonTemp
{
public:
NonTemp(NonTemp & tmp)
{
assert(&tmp == this);
}
};

class Guard : public NonTemp
{
public:
Guard(NonTemp & t, int i) : NonTemp(t), _i(i)
{
std::cout << "interesting Non Temporary hack my Chris
in******@gmail.com" << std::endl;
}
~Guard()
{
std::cout << "dest" << std::endl;
}
private:
int _i;
};
int main()
{
Guard g(g, 1);
std::cout << "middle" << std::endl;

// impossible to make a temp!
}
OK - while you're at it, you should also make the copy constructor and
assignment operator private and not implemented.
Mar 17 '07 #6

P: n/a
Gianni Mariani wrote:
Adrian Hawryluk wrote:
>Gianni Mariani wrote:
...
>>One suggestion is to not allow access to x other than through the
guard. i.e.

{
Guard g(x);

g.DoStuffToX( blah );
}

or even

{
Guard(x).DoStuffToX( blah );
}

That would mean you would need to stop pushing around raw ogl pointers.
Yeah, using the Guard as a proxy as Gianni suggested is the best way.
However, you are not guaranteed to have the destructor to be called at
any particular time. I.e. It will be destroyed between the last time
it is used to the end of the enclosing scope. When that will happen
depends on the compiler. To ensure that it is destroyed when you
expect, you must enclose the section with braces and not have other
things in it, just as Gianni's example shows.

The compiler would be non compliant if it deletes the temporary before
calling DoStuffToX in either case.
Ether case? I don't understand.

Calling DoStuffToX() would be the last case it was used, so deletion of
the proxy would happen sometime after the call to the end of the
enclosing scope.
Adrian
--
__________________________________________________ ___________________
\/Adrian_Hawryluk BSc. - Specialties: UML, OOPD, Real-Time Systems\/
\ My newsgroup writings are licensed under the Creative Commons /
\ Attribution-Noncommercial-Share Alike 3.0 License /
\_____[http://creativecommons.org/licenses/...sa/3.0/]_____/
\/______[blog:__http://adrians-musings.blogspot.com/]______\/
Mar 17 '07 #7

P: n/a
Yup good idea Gianni, sometimes I don't think of these things.
See what I use it for is like this, I have many functions and I don't
want to keep making helper functions (DoStuffToX), it would complicate
things.

void GlTexture2D::sendToGL(GlBuffer * buffer)
{
BindGuard g(g, this);
GlBuffer::BindBufferGuard bg(bg, buffer);
DEBUG_TIME(1, "sendToGL()");
glTexSubImage2D(target(), 0,
0 /*xoffset*/, 0 /*yoffset*/,
buffer->width(),
buffer->height(),
buffer->dataFormat(),
buffer->dataType(),
BUFFER_OFFSET(0));
}

On Mar 17, 8:16 am, Adrian Hawryluk <adrian.hawryluk-at-
gmail....@nospam.comwrote:
Gianni Mariani wrote:
Adrian Hawryluk wrote:
Gianni Mariani wrote:
...
>One suggestion is to not allow access to x other than through the
guard. i.e.
>{
Guard g(x);
> g.DoStuffToX( blah );
}
>or even
>{
Guard(x).DoStuffToX( blah );
}
>That would mean you would need to stop pushing around raw ogl pointers.
Yeah, using the Guard as a proxy as Gianni suggested is the best way.
However, you are not guaranteed to have the destructor to be called at
any particular time. I.e. It will be destroyed between the last time
it is used to the end of the enclosing scope. When that will happen
depends on the compiler. To ensure that it is destroyed when you
expect, you must enclose the section with braces and not have other
things in it, just as Gianni's example shows.
The compiler would be non compliant if it deletes the temporary before
calling DoStuffToX in either case.

Ether case? I don't understand.

Calling DoStuffToX() would be the last case it was used, so deletion of
the proxy would happen sometime after the call to the end of the
enclosing scope.

Adrian
--
__________________________________________________ ___________________
\/Adrian_Hawryluk BSc. - Specialties: UML, OOPD, Real-Time Systems\/
\ My newsgroup writings are licensed under the Creative Commons /
\ Attribution-Noncommercial-Share Alike 3.0 License /
\_____[http://creativecommons.org/licenses/...sa/3.0/]_____/
\/______[blog:__http://adrians-musings.blogspot.com/]______\/

Mar 17 '07 #8

This discussion thread is closed

Replies have been disabled for this discussion.