提问人:Luchian Grigore 提问时间:8/31/2011 最后编辑:Luchian Grigore 更新时间:6/26/2012 访问量:143
将方法调用限制为另一个方法
Restricting method call to another method
问:
对此可能有一个相当简单和直接的答案,但由于某种原因我看不到它。 我需要将类中的调用方法限制为仅由某些接口的派生类实现的某些方法。
说我有
class A{
public:
static void foo();
};
class myInterface{
public:
virtual void onlyCallFooFromHere() = 0;
}
class myImplementation : public myInterface{
public:
virtual void onlyCallFooFromHere()
{
A::foo(); //this should work
}
void otherFoo()
{
A::foo(); //i want to get a compilation error here
}
}
所以我应该只能从方法调用A::foo
onlyCallFooFromHere()
有没有办法实现这一目标?我愿意接受任何建议,包括更改课程设计。
编辑:
所以。。。我觉得有必要进一步解释这个问题。我有一个与数据库交互的实用程序类(主要是更新记录) - 类 A。 在我的接口(表示一个基本的数据库对象)中,我有虚函数 updateRecord(),我从中调用 db 实用程序类的方法。我只想在所有扩展类的 updateRecord() 函数中强制更新数据库,而不是在其他任何地方。我不认为这是一个糟糕的设计选择,即使不可能。但是,如果确实不可能,我将不胜感激不同的解决方案。
答:
您可以将项目拆分为不同的 TU:
// A.h
class A
{
public:
static void foo();
};
// My.h
class myInterface
{
public:
virtual void onlyCallFooFromHere() = 0;
}
class myImplementation : public myInterface
{
public:
virtual void onlyCallFooFromHere();
void otherFoo();
};
// My-with-A.cpp
#include "My.h"
#include "A.h"
void myImplementation::onlyCallFooFromHere() { /* use A */ }
// My-without-A.cpp
#include "My.h"
void myImplementation::otherFoo() { /* no A here */ }
评论
aspace::A::f()
A.h
onlyCallFooFromHere()
改变班级设计 - 你想要的是不可能的。
我不确定你想用这么少的细节实现什么,我无法进一步评论。
评论
您可能知道这一点,但通过继承,您可以拥有公共、受保护和私有成员访问权限。
如果成员在基类中是私有的,则派生无法访问它,而如果同一成员受到保护,则派生类可以访问它(虽然它仍然不是公共的,因此您正在维护封装)。
但是,没有办法阻止特定函数能够查看其范围内可用的内容(这是您要问的),但您可以设计基类,以便派生类只能访问它的特定元素。
这可能很有用,因为类 B 可以从受保护的类 A 继承(从而获得其受保护的成员),而类 C 可以从与公共类相同的类 A 继承(因此无法访问其受保护的成员)。这将使你至少获得某种形式的调用可用性差异 - 但是在类之间,而不是在同一类中的函数之间。
评论
C
A
A
C
A
C
C
这可能有效。
class myInterface;
class A {
private:
friend class myInterface;
static void foo();
};
class myInterface {
public:
virtual void onlyCallFooFromHere() {callFoo();}
protected:
void callFoo() {A::foo();}
};
虽然在这一点上,我想我只是将 A::foo 设为 myInterface 的静态。这些担忧不再是分开的。
class myInterface {
protected:
static void foo();
};
foo 在 A 中有什么原因吗?
[免责声明:此解决方案将阻止墨菲,而不是马基雅维利。
怎么样:
class DatabaseQueryInterface {
public:
~virtual DatabseQueryInterface() = 0;
virtual Query compileQuery() const = 0; // or whatever
virtual ResultSet runQuery(const Query&) const = 0; // etc
};
class DatabaseUpdateInterface : public DatabaseQueryInterface {
public:
virtual Update compileUpdate() const = 0; // whatever
};
class DatabaseObject {
public:
virtual ~DatabaseObject() = 0;
protected:
virtual void queryRecord(const DatabaseQueryInterface& interface) = 0;
virtual void updateRecord(const DatabaseUpdateInterface& interface) = 0;
};
class SomeConcreteDatabaseObject : public DatabaseObject {
protected:
virtual void updateRecord(const DatabaseUpdateInterface& interface) {
// gets to use interface->compileUpdate()
}
virtual void queryRecord(const DatabaseQueryInterface& interface) {
// only gets query methods, no updates
}
};
因此,基本思想是,基类会释放一个私有对象和一个私有对象,当需要调用子类的受保护成员时,它会将接给方法,并将接给方法。DatabaseObject
Query
Update
Update
updateRecord()
Query
queryRecord()
这样一来,子类的自然做法就是使用它们传递的对象来与数据库通信。当然,他们总是可以诉诸肮脏的伎俩来存储传入的对象,并尝试稍后从查询方法使用它,但坦率地说,如果他们走得太远,他们就只能靠自己了。Update
评论
A
myImpl