[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.c++

Interfaces, restricting access

Christopher

10/19/2008 12:42:00 AM

I am surprised this hasn't come up for me more in the past, but the
situation is:

I need to have an interface that is usable for all
I need to have an interface that is only usable for some

I do not really know of a good way to achieve this. If I use friend
functions, I can no longer make methods virtual, right?

Example:

I am making a texture class for my graphics library

The only thing the application should have access to is a string
filename to create it with, perhaps dimensions, and a few other
things.

However, some classes inside the engine, such as say the renderer
should have access to the hardware level texture resource, which is in
this case a pointer to a struct from a 3rd party library. So, I need
accessors for my renderer to use, but do not want them to be available
to the application. Both are using the same class.


4 Answers

Salt_Peter

10/19/2008 3:41:00 AM

0

On Oct 18, 8:41 pm, Christopher <cp...@austin.rr.com> wrote:
> I am surprised this hasn't come up for me more in the past, but the
> situation is:
>
> I need to have an interface that is usable for all
> I need to have an interface that is only usable for some
>
> I do not really know of a good way to achieve this. If I use friend
> functions, I can no longer make methods virtual, right?
>
> Example:
>
> I am making a texture class for my graphics library
>
> The only thing the application should have access to is a string
> filename to create it with, perhaps dimensions, and a few other
> things.
>
> However, some classes inside the engine, such as say the renderer
> should have access to the hardware level texture resource, which is in
> this case a pointer to a struct from a 3rd party library. So, I need
> accessors for my renderer to use, but do not want them to be available
> to the application. Both are using the same class.

Provide access(...) using interfaces only

We need a dummy Resource,
a core Texture type (string member and a pointer)
application needs an interface: IApplication
renderer needs another interface: IRenderer
type Texture overloads access(...) based on interface type.

#include <iostream>

struct Resource
{
};

struct IApplication
{
virtual void set(const std::string&) = 0;
};

struct IRenderer
{
virtual void set(Resource* p) = 0;
};

class Texture
{
const std::string m_s;
Resource* p_res;
public:
Texture(std::string s) : m_s(s), p_res(0) { }
void access(IApplication& ia) const
{
ia.set(m_s);
}
void access(IRenderer& ir) const
{
ir.set(p_res);
}
void setp(Resource* p)
{
p_res = p;
}
};

class Application : public IApplication
{
std::string m_s;
public:
void set(const std::string& r_s)
{
m_s = r_s;
}
void display() const
{
std::cout << m_s << std::endl;
}
};

class Renderer : public IRenderer
{
Resource* p_res;
public:
void set(Resource* p)
{
p_res = p;
}
void display() const
{
std::cout << p_res << std::endl;
}
};

int main()
{
// setup an environment
Resource res;
Texture tex("some string");
tex.setp( &res );

// application's access
Application app;
tex.access( app );
app.display();

// renderer's access
Renderer rend;
tex.access( rend );
rend.display();
}

/*
some string
0x7fff4c23687f
*/

Christopher

10/19/2008 6:59:00 AM

0

On Oct 18, 10:40 pm, Salt_Peter <pj_h...@yahoo.com> wrote:
> On Oct 18, 8:41 pm, Christopher <cp...@austin.rr.com> wrote:
>
>
>
>
>
> > I am surprised this hasn't come up for me more in the past, but the
> > situation is:
>
> > I need to have an interface that is usable for all
> > I need to have an interface that is only usable for some
>
> > I do not really know of a good way to achieve this. If I use friend
> > functions, I can no longer make methods virtual, right?
>
> > Example:
>
> > I am making a texture class for my graphics library
>
> > The only thing the application should have access to is a string
> > filename to create it with, perhaps dimensions, and a few other
> > things.
>
> > However, some classes inside the engine, such as say the renderer
> > should have access to the hardware level texture resource, which is in
> > this case a pointer to a struct from a 3rd party library. So, I need
> > accessors for my renderer to use, but do not want them to be available
> > to the application. Both are using the same class.
>
> Provide access(...) using interfaces only
>
> We need a dummy Resource,
> a core Texture type (string member and a pointer)
> application needs an interface: IApplication
> renderer needs another interface: IRenderer
> type Texture overloads access(...) based on interface type.
>
> #include <iostream>
>
> struct Resource
> {
>
> };
>
> struct IApplication
> {
>   virtual void set(const std::string&) = 0;
>
> };
>
> struct IRenderer
> {
>   virtual void set(Resource* p) = 0;
>
> };
>
> class Texture
> {
>   const std::string m_s;
>   Resource* p_res;
> public:
>   Texture(std::string s) : m_s(s), p_res(0) { }
>   void access(IApplication& ia) const
>   {
>     ia.set(m_s);
>   }
>   void access(IRenderer& ir) const
>   {
>     ir.set(p_res);
>   }
>   void setp(Resource* p)
>   {
>     p_res = p;
>   }
>
> };
>
> class Application : public IApplication
> {
>   std::string m_s;
> public:
>   void set(const std::string& r_s)
>   {
>     m_s = r_s;
>   }
>   void display() const
>   {
>     std::cout << m_s << std::endl;
>   }
>
> };
>
> class Renderer : public IRenderer
> {
>   Resource* p_res;
> public:
>   void set(Resource* p)
>   {
>     p_res = p;
>   }
>   void display() const
>   {
>     std::cout << p_res << std::endl;
>   }
>
> };
>
> int main()
> {
>   // setup an environment
>   Resource res;
>   Texture tex("some string");
>   tex.setp( &res );
>
>   // application's access
>   Application app;
>   tex.access( app );
>   app.display();
>
>   // renderer's access
>   Renderer rend;
>   tex.access( rend );
>   rend.display();
>
> }
>
> /*
> some string
> 0x7fff4c23687f
> */- Hide quoted text -
>
> - Show quoted text -


Not sure I follow.
You now have an Application class that is a Texture or at least has
methods and data specific to the texture.
Maybe I am just getting confused on names and made it too specific.


class A
{
public:

// Can be called by anyone
virtual void Method1();
virtual void Method2();
virtual void Method3();

// Can only be called by a class C
virtual void Method4();
virtual void Method5();

private:

// All 5 methods manipulate this data a differant way
int * m_data;
};

class B
{
public:
Foo()
{
A * a = new A();
a->Method1();

// Not allowed!
a->Method5();
}
};


class C
{
Bar()
{
A * a = new A();
a->Method1();

// Is OK
a->Method5();
}
};

CockneyWinker

10/19/2008 7:27:00 AM

0


"Christopher" <cpisz@austin.rr.com> wrote in message
news:d0e37890-8f9d-46ab-8ff2-d4d263b013c6@m36g2000hse.googlegroups.com...
>I am surprised this hasn't come up for me more in the past, but the
> situation is:
>
> I need to have an interface that is usable for all
> I need to have an interface that is only usable for some
>
> I do not really know of a good way to achieve this. If I use friend
> functions, I can no longer make methods virtual, right?
>
> Example:
>
> I am making a texture class for my graphics library
>
> The only thing the application should have access to is a string
> filename to create it with, perhaps dimensions, and a few other
> things.
>
> However, some classes inside the engine, such as say the renderer
> should have access to the hardware level texture resource, which is in
> this case a pointer to a struct from a 3rd party library. So, I need
> accessors for my renderer to use, but do not want them to be available
> to the application. Both are using the same class.
>
>

How about something like this below. I've created a class hierarchy based
upon an abstract interface for a "renderer" and
and "advanced" renderer subclass, and two rendering engines, an ordinary and
an advanced.
You create the "advanced" renderer and pass it to the two engines, the
ordinary engine is
expecting an ordinary renderer and so only uses methods of the ordinary
render, and the advanced
engine expects the Full Monty.



#include <iostream>



class IRenderer{

public:

virtual void render () = 0;

};

class IAdvancedRenderer : public IRenderer

{

public:

virtual void render () = 0;

virtual void renderAdvanced() = 0;



};

class RendererImpl : public IAdvancedRenderer

{

public:

RendererImpl(){}

virtual void render(){ std::cout << "Render" << std::endl;}

virtual void renderAdvanced(){ std::cout << "Advanced Render" <<
std::endl;}

};



class RenderingEngine

{

public:

RenderingEngine( IRenderer& renderer)

:_renderer(renderer)

{}



void render()

{

_renderer.render();

}

private:

IRenderer& _renderer;

};



class AdvancedRenderingEngine

{

public:

AdvancedRenderingEngine( IAdvancedRenderer& renderer)

:_renderer(renderer)

{}

void renderAdvanced()

{

_renderer.renderAdvanced();

}

void render()

{

_renderer.render();

}

private:

IAdvancedRenderer& _renderer;

};

IAdvancedRenderer* createRenderer()

{

return new RendererImpl();

}



int main(int argc, char *argv[])

{

RendererImpl renderer ;



AdvancedRenderingEngine advancedEngine( renderer);

RenderingEngine ordinaryEngine( renderer);





ordinaryEngine.render();

advancedEngine.renderAdvanced();



return 0;

}




Erik Wikström

10/19/2008 8:41:00 AM

0

On 2008-10-19 02:41, Christopher wrote:
> I am surprised this hasn't come up for me more in the past, but the
> situation is:
>
> I need to have an interface that is usable for all
> I need to have an interface that is only usable for some
>
> I do not really know of a good way to achieve this. If I use friend
> functions, I can no longer make methods virtual, right?

Not sure exactly what you mean by that, a friend function/class can call
a virtual function (as shown in this, somewhat contrived, example):

#include <iostream>

class PubInterface
{
public:
virtual void PubFunc() = 0;
};

class PrivInterface
{
virtual void PrivFunc() = 0;
friend void doIt(PubInterface&);
};

void doIt(PubInterface& i)
{
i.PubFunc();

PrivInterface* pi = dynamic_cast<PrivInterface*>(&i);
if (pi != 0)
pi->PrivFunc();
}

class Impl1 : public PubInterface
{
public:
void PubFunc()
{
std::cout << "PubFunc()\n";
}
};

class Impl2 : public PubInterface, public PrivInterface
{
void PrivFunc()
{
std::cout << "PrivFunc()\n";
}

public:
void PubFunc()
{
std::cout << "PubFunc()\n";
}
};


int main()
{
Impl1 i1;
Impl2 i2;

doIt(i1);
doIt(i2);

return 0;
}

--
Erik Wikström