对此可能有一个相当简单和直接的答案,但由于某种原因我无法看到它。 我需要将类中的调用方法限制为某些接口的派生类实现的某些方法。
说我有
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()函数中更新数据库,而不是其他任何地方。即使不可能,我也不认为这是一个糟糕的设计选择。但是,如果确实不可能,我将不胜感激。
答案 0 :(得分:3)
改变班级设计 - 你想要的是不可能的。
我不确定你想用这么少的细节来实现什么,我无法进一步评论。
答案 1 :(得分:1)
[免责声明:此解决方案将阻止Murphy,而不是Macchiavelli。]
怎么样:
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
对象并尝试稍后从查询方法中使用它,但坦率地说,如果它们达到这样的长度,它们就是自己的。 / p>
答案 2 :(得分:0)
您可以将项目拆分为不同的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 */ }
答案 3 :(得分:0)
您可能知道这一点,但通过继承,您可以拥有公共,受保护和私有成员访问权限。
如果一个成员在基类中是私有的,派生者就无法访问它,而如果同一个成员受到保护,那么派生类可以访问它(虽然它仍然不是公共的,所以你要保持封装)
没有办法阻止特定函数在其范围内看到可用的内容(这就是您要问的内容),但您可以设计基类,以便派生类只能访问它的特定元素
这可能很有用,因为B类可以从A类继承为受保护(因此获得其受保护的成员),而C类可以从同一个A类继承为public(因此无法访问其受保护的成员)。这将使您至少在某些类之间获得某种形式的调用可用性差异 - 但不是在同一类中的函数之间。
答案 4 :(得分:0)
这可行。
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?