- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
这是我遇到的意外问题。我正在编写一个GUI应用程序,并且使用GUI库中的两个类:Model类和View类。 Model的内容由View类呈现到屏幕上。在某个时候,我决定派生Model类,因为我需要扩展功能。该库的类是派生的,我发现了许多示例。这很容易并且完美地工作了。
现在有一个问题:Model类提供了直接编辑模型数据的方法。我不希望这些方法公开,因为我写了包装器,而这些包装器必须是唯一的编辑方法。我确实需要继承,因为派生的MyModel覆盖了Model类的许多虚拟方法。所以我在想该怎么办。以下是所有详细信息的摘要:
protected
或
private
下编写所有Model的编辑方法的方法声明,以便将它们隐藏。这很好用,但是维护方面有一个小问题:如果在库的 future 版本中,模型接口(interface)会发生变化,例如添加了新的编辑方法,我们必须将其作为私有(private)/ protected 方法手动添加到MyModel类中。当然,我可以跟踪库的更改,或者至少可以转到其在线API参考并浏览Model类参考页面,以确保没有任何更改,或者在必要时在生产/稳定版本的CD之前更新我的代码。我的申请被释放。
public
继承(用于迭代接口(interface))和从Model的
protected/private
继承(以隐藏Model的编辑接口(interface))。
namespace GUI
{
class BasicModel
{
public:
/* iteration interface for observing the model */
iterator get_iter();
// but no data here, it's just an interface which calls protected virtual methods
// which are implemented by deriving classes, e.g. Model
protected:
virtual iterator get_iter_vfunc() = 0;
virtual void handle_signal();
};
class Model : public BasicModel
{
/* inherits public iteration interface*/
/* implements observation virtual methods from BasicModel*/
virtual iterator get_iter_vfunc() { /*...*/ }
/* has private data structures for the model data */
std::vector<Row> data;
/* has public editing interface, e.g. insert_row(), erase(), append()
/* has protected drag-n-drop related virtual methods*/
virtual void handle_drop();
};
}
class MyModel : public GUI::Model
{
/* implements virtual methods from BasicModel, e.g. default signal handlers*/
virtual void handle_signal() { /*...*/ }
/* implements drag-n-drop virtual methods from Model*/
virtual void handle_drop() { *...* }
/* inherits public iteration interface*/
/* inherits public editing interface (***which I want to hide***)
/* implements its own editing mechanism*/
void high_level_edit (int param);
};
#include <iostream>
class Base
{
public:
void func ()
{
std::cout << "Base::func() called" << std::endl;
func_vfunc ();
}
protected:
virtual void func_vfunc ()
{
std::cout << "Base::func_vfunc() called" << std::endl;
}
};
class Derived : public Base
{
protected:
virtual void func_vfunc ()
{
std::cout << "Derived::func_vfunc() called" << std::endl;
}
};
class MyClass : public Base, private Derived
{
};
int main (int argc, char* argv[])
{
Base base;
Derived derived;
MyClass myclass;
base.func ();
derived.func ();
myclass.func ();
return 0;
}
myclass.func()
的调用含糊不清,但由于私有(private)继承,我们认为其中之一是私有(private)的
func()
,因此我不明白为什么它无法编译。最重要的是,假设这不是一个错误,但只是我不了解事情是如何工作的-建议的多重继承解决方案是不可能的。如果我没记错的话,解决此问题的唯一方法是虚拟继承,但是我不能使用它,因为我使用的类是库类,并且它们不使用虚拟继承。而且即使那样,由于我同时使用私有(private)继承和公共(public)继承,所以它可能无法解决问题,仍然是一个模棱两可的选择。
最佳答案
如果我正确理解了您的问题,则可能应该混合使用继承(MyModel源自BaseModel)和组合(MyModel包含Model的私有(private)实例)。
然后在MyModel中使用您自己的基本虚拟方法的实现,对于那些您不想重新实现的方法,只需使其成为相应的Model方法的代理即可。
无论如何,恕我直言,您应该避免多重继承。否则,随着时间的流逝,它可能会变得很毛茸茸。
编辑:现在我可以看到代码,我再给它一个镜头。
您需要做的是重新实现MyModelImpl类(来自Model的派生类)中需要的内容,该类将隐藏在代理类MyModel(BaseModel的派生类)中。我的第一个想法非常相似,只是我不了解您需要重新实现Model的某些部分。
类似于以下内容:
class MyModel : public BaseModel {
public:
void high_level_edit(int param) { m_impl.high_level_edit(param); }
protected:
virtual iterator get_iter_vfunc() { return m_impl.get_iter_vfunc(); }
virtual void handle_signal() { m_impl.handle_signal(); }
private:
class MyModelImpl : public Model {
public:
void high_level_edit(int param);
// reimplement whatever you need (methods present in BaseModel,
// you need to call them from MyModel proxies)
virtual iterator get_iter_vfunc() { /*...*/ }
protected:
// reimplement whatever you need (methods present only in Model,
// you don't need to call them from MyModel proxies)
virtual void handle_drop();
};
MyModelImpl m_impl;
};
关于c++ - C++多重继承和访问说明符:从基类及其派生继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14909071/
经过几个小时的(重新)搜索,我无法想出普通抽象类和使用模板模式之间的可解释区别。 我唯一看到的是: 使用抽象类时,您需要实现所有方法。但是在使用模板方法时,您只需要实现这两个抽象方法。 有人可以向我解
我正在尝试实现一种算法,该算法可找到以下形状给出的外多边形的每个单独边的对应区域。也就是说,1,2 边的相应区域是 [1,6,7,8,2],2,3 边的区域是 [2,8,3] 等等,CCW 或 CW
我正在尝试在派生 self 的 BaseController 类的任何 Controller 上自动设置一个属性。这是我的 Application_Start 方法中的代码。 UnitOfWork 属
我正在使用 mgcv 包通过以下方式将一些多项式样条拟合到一些数据: x.gam smooth$knots [1] -0.081161 -0.054107 -0.027053 0.000001
考虑以下代码: void foo(){ ..... } int main() { int arr[3][3] ; char string[10]; foo();
本书The c++ programming language有这个代码: class BB_ival_slider : public Ival_slider, protected BBslider {
是否有一个 package.json 属性可用于指定模块解析应启动的根文件夹? 例如,假设我们在 node_modules/mypackage/src/file1 中有一个安装。我们要导入的所有文件都
我正在尝试使用聚合函数来实现与 SQL 查询相同的结果: 查询语句: sqldf(" SELECT PhotoID, UserID,
我正在比较使用 LOESS 回归的两条线。我想清楚地显示两条线的置信区间,我遇到了一些困难。 我尝试过使用各种线型和颜色,但在我看来,结果仍然是忙碌和凌乱。我认为置信区间之间的阴影可能会使事情变得更清
给定这段代码 public override void Serialize(BaseContentObject obj) { string file = ObjectDataStoreFold
我正在构建某种工厂方法,它按以下方式将 DerivedClass 作为 BaseClass 返回: BaseClass Factory() { return DerivedClass(); }
当重写 class delegation 实现的接口(interface)方法时,是否可以调用通常从重写函数中委托(delegate)给的类?类似于使用继承时调用 super 的方式。 来自docum
我有一个基类 fragment (如下所示)。我在其他 3 个 fragment 类中扩展了此类,每个类都共享需要在这 3 个 fragment 中访问的相同 EditText。因此,我在基类中设置了
如何在不加载额外库的情况下在 R 中计算两个排列之间的 Kendall tau 距离(又名冒泡排序距离)? 最佳答案 这是一个 O(n.log(n)) 的实现,在阅读后拼凑而成,但我怀疑可能有更好的
情况 我创建了一个具有国际化 (i18n) 的 Angular 应用程序。我想在子域中托管不同的版本,例如: zh.myexample.com es.myexample.com 问题 当我使用命令 n
std::is_base_of 之间的唯一区别和 std::is_convertible是前者在 Base 时也成立是 私有(private)或 protected Derived 的基类.但是,您何
我创建了一个名为 baseviewcontroller 的父类(super class) uiviewcontroller 类,用于包含大多数应用屏幕所需的基本 UI。它包括一个自定义导航栏和一个“自
我是一名优秀的程序员,十分优秀!