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

Interfaces, restricting access

P: n/a
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.
Oct 19 '08 #1
Share this Question
Share on Google+
4 Replies


P: n/a
On Oct 18, 8:41 pm, Christopher <cp...@austin.rr.comwrote:
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
*/
Oct 19 '08 #2

P: n/a
On Oct 18, 10:40*pm, Salt_Peter <pj_h...@yahoo.comwrote:
On Oct 18, 8:41 pm, Christopher <cp...@austin.rr.comwrote:


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();
}
};

Oct 19 '08 #3

P: n/a

"Christopher" <cp***@austin.rr.comwrote in message
news:d0**********************************@m36g2000 hse.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;

}


Oct 19 '08 #4

P: n/a
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
Oct 19 '08 #5

This discussion thread is closed

Replies have been disabled for this discussion.