• Advertisement

Archived

This topic is now archived and is closed to further replies.

Is this acceptable?

This topic is 5936 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

for a personal project I am creating a series of components for C++ Builder which manipulate D3D8. Now then..... Is this generally seen as acceptable? class D3D { private: LPDIRECT3DDEVICE device; : : public: LPDIRECT3DDEVICE GetDevice(); : : }; and then passing that Device to a model class to render I am a bit worried about the GetDevice() because a: it exposes the main part of the class to the open world. b: means having many copies of the Device object in the models (could be static I know but thats for later) c: makes code unreadable i.e. Model->initialize(Scene->GetDevice()); - we shouldn''t put the programmer through this should we? Ideas and notes would be welcomed Neil

Share this post


Link to post
Share on other sites
Advertisement
First of all I'm sure somebody is going to have a much better answer to this that I have, but I'll explain it as I've been taught:

Having an accessor method like GetDevice() is seen as a safer method of exposing the class variables because it is impossible to accidently change the value of device through it (i.e. you can't do D3DObject->GetDevice() = new LPDIRECT3DDEVICE(); ) whereas you could do D3DObject.device = new LPDIRECT3DDEVICE();. This isn't a great example, but imagine you had two LPDIRECT3DDEVICE's and wanted to check if they were the same. It would be very easy to do:
if (D3DObject1.device = D3DObject2.device)
but this would make the two devices equal instead of testing them. Using accessor methods avoids these potential problems.

EDIT: stupid smilies!

Edited by - Enigma on November 19, 2001 10:56:23 AM

Share this post


Link to post
Share on other sites
BUT....
What if someone says
LPDIRECT3DDEVICE dev=Scene->GetDevice();

Firstly I dont want the component user to have access to change environment settings - this could mess things up in the app if the setting isn''t supported (basic example - if texturing is set to multitexture on a card with only one texture unit (OK it''s a bad example as most cards do have support for multitexture)).

Also i see it as bad practice to HAVE to call a method like this
Model->Init(Scene->GetDevice());

The idea is that the user shouldn''t know/care what is doing the drawing (therefore we cannot assume familiarity with D3D) and the components must be easy to use (if only for my own sake).

Would ''friend''s work? I''ve read about them but the syntax isn''t obvious to me. Any help.

Cheers

Neil

Share this post


Link to post
Share on other sites
If you don''t want the component user to be able to change things in the LPDIRECT3DDEVICE, then just make the accessor method return a copy of it (if this is possible, I don''t actually know what an LPDIRECT3DDEVICE is!), that way the component user can read any information they need but any changes will have no effect on the D3D class.

I agree that

Model->Init(Scene->GetDevice());

is a bit messy, but it''s not that much worse than

Model->Init(Scene.device);

and if you dereferenced the pointers you could write it as:

Model.Init(Scene.getDevice());

Or, if you wanted to be a bit fancy, find a character you don''t use (~ maybe) and #define this to ->. Now you can write:

Model~Init(Scene~getDevice());

Or as another alternative, simply make your Init method get the device itself:

Model->Init(Scene);

void Model::Init(SceneThing* Scene){
LPDIRECT3DDEVICE device = Scene->getDevice();
DoStuff();
}

I would suggest that any changes that can be made to the LPDIRECT3DDEVICE should be forced to be made through the D3D class, i.e.

D3DObject.setAttribute#1(value)

This will entirely hide the LPDIRECT3DDEVICE from the rest of the program.

Share this post


Link to post
Share on other sites
i am pretty far from knowing much about Direct3D, but i think that LPDIRECT3DDEVICE is a pointer (it''s that hungarian notation or whatever... LP = long pointer). so, you are just returning (or passing around, or copying) a pointer.
i''m fairly new to c++ also, but they might be able to mess with the device''s internal members because of this (device->messMeUp(void)). on this one, though, i''m not sure, so hopefully someone who is knowledgable will tell me to shut up and give you a complete answer.

--- krez (krezisback@aol.com)

Share this post


Link to post
Share on other sites
Thanx for the input. For those not in the know
an LPDIRECT3DDEVICE is a pointer to a Direct3DDevice object.

If i was to pass back a de-referenced instance of the object it could be incredibly slow - also I don''t think that the Model class could use it then as it''s NOT the original object (it''s just a copy of it). I''m not going to make Device public (the thought never crossed my mind (honest)) but passing back a pointer to the instance of that object just seems ''dangerous'' and produces unreadble code. I have a lttle knowledge of friends (where a stated object has access to another objects private methods and variables), but i don''t actually knw how to use them.

the code I have seen looks a little like this

class D3D
{
private:
friend LPDIRECT3DDEVICE Device;
:
:
public:
:
:
};

BUT how does the compiler know what the LPDIRECT3DDEVICE is the friend of?

Cheers again

and thanks for the views even though i''m not quite there yet you have at least got rid of some possibilities (and made me look up a couple of things - something we should all do more before asking silly questions)

Neil

Share this post


Link to post
Share on other sites
you can declare a function outside the class with the friend keyword:
    
class FooClass
{
private:
int someVar, otherVar;
:
:
public:
friend int DaFunction(FooClass);
:
:
};
:
:
int DaFunction(FooClass Bah)
{
return Bah.someVar;
};

you can also make a class a friend of another class, so the latter can access the private stuff in the former:

class FooClass;
class BahClass
{
private:
int thisVar, thatVar;
public:
int UseMyFriend(FooClass);
};
int BahClass::UseMyFriend(FooClass Foo)
{
return Foo.someVar;
};
class FooClass
{
private:
int someVar, otherVar;
public:
friend class BahClass;
};

so basically, you do not declare the LPDIRECT3DDEVICE as a friend, you declare the function (or class) that can use it as a friend (in the public part of the class).

--- krez (krezisback@aol.com)

Edited by - krez on November 19, 2001 7:16:42 PM

Share this post


Link to post
Share on other sites
Create a singleton class, so there''s only one copy of the LPDIRECT3DDEVICE hanging around. You should also consider redesigning your class framework if your model requires a pointer to the device for its initialization. Encapsulate in entirety as many objects as possible so that they do not depend on each other unless absolutely necessary.

Share this post


Link to post
Share on other sites
Cheers Krez - I understand it now (at least what you wrote).
Just wanted to say thanks - i''m going to do it this afternoon

Cheers

Neil

Share this post


Link to post
Share on other sites
Don''t forget to increase the reference count of the device pointer when you are passing it around like that and then decrease it when you''re done.

"You are too useless. And now I must beat you." - English subtitle in a Honk Kong Movie.

Share this post


Link to post
Share on other sites
Friend classes/functions rather tend to nullify the advantages of accessor methods.

Anyway, rather than have an accessor to get the surface, why not have methods on your wrapper class to manipulate it? If your client doesn''t necessarily know anything about D3D, why expose them to any of the gory details?

--

MP3 Dancer

Get A Stripper on your desktop

Share this post


Link to post
Share on other sites
I''m not sure if your familiar with builder so i''ll assume your not. In builder there are ways that can allow components be related to other components. (by the IDE before compilation)

As the model and scene components are separate i was thinking that in the code for the initialization of model i would need to have

void TModel::Init(TScene* scene)
{
device=scene->GetDevice();
}

the problem with this is that I would then be exposing a property (or rather a pointer to it) because Getdevice() would HAVE to be public. If the user comes along and sees a GetDevice and plays around (C++ Builder allows shortcuts in the same way as Internet Expolorer so when I type scene-> it displays all of the methods associated with it (public ones anyway). I cant rely on them having this option turned off and I dont want to expose the Device to anyone. As I am also writing the TModel class I think the friend mechanism works pretty well.

I wont be exposing the user to any methods of D3D - i will be defining methods do the dirty work - i.e. add fog, add lights, draw the model - all without a single reference to D3D by the user.

Neil

Share this post


Link to post
Share on other sites

  • Advertisement