首页 \ 问答 \ 插入扩展抽象实体的实体时出错(Error when inserting entities which extend an Abstract Entity)

插入扩展抽象实体的实体时出错(Error when inserting entities which extend an Abstract Entity)

我有以下实体:

  • User 具有用户名,邮件等的公共用户实体
  • ComputerUserWithAI 。 与用户类似,但它由应用程序控制。
  • Pick 。 包含与Game的关系,它应该拥有一个选择器。

由于Picker可以是UserComputerUserWithAI我创建了一个名为PickerAbstract Entity ,我使UserComputerWithAI扩展了Picker类。 一旦我添加了Picker实体,我就Pick与被称为picker的Picker实体有关系。

一切都很顺利,但我不能将一个ComputerUserWithAI插入一个Pick 。 我的代码是这样的:

ComputerUserWithAI *userWithAI = [NSEntityDescription insertNewObjectForEntityForName:@"ComputerUserWithAI" inManagedObjectContext:ctx];
userWithAI.name = @"DeepBlue";

Pick *pick = [NSEntityDescription insertNewObjectForEntityForName:@"Pick" inManagedObjectContext:ctx];
pick.game = game;
pick.picker = userWithAI;

我得到的错误如下:

由于未捕获的异常'NSInvalidArgumentException'而终止应用程序,原因:'对于一对一关系的值不可接受的类型:property =“picker”; 所需类型=选择器; 给定type = NSManagedObject; value =(entity:ComputerUserWithAI ...

但当我这样做时:

pick.picker = [NSEntityDescription insertNewObjectForEntityForName:@"Picker" inManagedObjectContext:ctx];

它确实有效。

我从核心数据检查了生成的类,他们正在扩展抽象实体。 可能有什么问题?


I have the following entities:

  • User. The common user entity with username, mail, etc.
  • ComputerUserWithAI. Similar to user but it's controlled by the application.
  • Pick. Contains a relation to Game and it should hold a picker.

Since a Picker can be an User or a ComputerUserWithAI I created an Abstract Entity called Picker and I made User and ComputerWithAI extend that Picker class. Once I added the Picker entity I made Pick have a relation to the Picker entity called picker.

Everything went fine, but I can't insert a ComputerUserWithAI to a Pick. My code is like this:

ComputerUserWithAI *userWithAI = [NSEntityDescription insertNewObjectForEntityForName:@"ComputerUserWithAI" inManagedObjectContext:ctx];
userWithAI.name = @"DeepBlue";

Pick *pick = [NSEntityDescription insertNewObjectForEntityForName:@"Pick" inManagedObjectContext:ctx];
pick.game = game;
pick.picker = userWithAI;

The error I get is the following:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Unacceptable type of value for to-one relationship: property = "picker"; desired type = Picker; given type = NSManagedObject; value = (entity: ComputerUserWithAI...

But when I do:

pick.picker = [NSEntityDescription insertNewObjectForEntityForName:@"Picker" inManagedObjectContext:ctx];

it does work.

I checked the generated classes from core data and they are extending the Abstract Entity correctly. What might be wrong?


原文:https://stackoverflow.com/questions/7462530
更新时间:2022-03-11 19:03

最满意答案

既然你现在澄清了你想要的是访客模式,那么,对不起,但这就是它的样子。 这个答案显示了双重调度的访问者模式是如何工作的。


我想到了一个使用CRTP的好方法,但根据具体情况,这可能适用于您,也可能不适合您。
(注意:我使用了链接答案中的代码,所以名称不匹配,但我希望你能得到这个想法。)

// your Z
class Visitor;

// superclass needed for generic handling
struct Superbase{
  virtual void Accept(Visitor& v) = 0;
};

// your A
template<class Der>
class Base : public Superbase{
public:
    void Accept(Visitor& v){
        v.Visit(static_cast<Der&>(*this));
    }
};

// your B
class Derived1 : public Base<Derived1> {
};

// new C
class Derived2 : public Base<Derived1> {
};

class Visitor {
public:
    virtual void Visit(Superbase& sup){
      // generic handling of any Superbase-derived type
    }

    virtual void Visit(Derived1& d1){
      // handle Derived1
    }

    virtual void Visit(Derived2& d2){
      // handle Derived1
    }
};

int main(){
    Visitor v;
    Derived1 d1;
    d1.Accept(v);
}

唯一的问题是:现在你错过了为任何类型的 A设置泛型句柄的机会,因为函数不能同时是虚拟和模板。 :|
刮了一下,找到了一个使用Superbase基类的解决方案。 :)这甚至允许您拥有Superbase的容器并充分利用多态性。 :)


Since you now clarified that what you want is the visitor pattern, well, sorry, but that's just how it is. This answer shows how the visitor pattern with double dispatch works.


I thought of a nice way using CRTP, but this may or may not work for you, depending on the circumstances.
(Note: I used the code from the linked answer, so the names don't match, but I hope you get the idea.)

// your Z
class Visitor;

// superclass needed for generic handling
struct Superbase{
  virtual void Accept(Visitor& v) = 0;
};

// your A
template<class Der>
class Base : public Superbase{
public:
    void Accept(Visitor& v){
        v.Visit(static_cast<Der&>(*this));
    }
};

// your B
class Derived1 : public Base<Derived1> {
};

// new C
class Derived2 : public Base<Derived1> {
};

class Visitor {
public:
    virtual void Visit(Superbase& sup){
      // generic handling of any Superbase-derived type
    }

    virtual void Visit(Derived1& d1){
      // handle Derived1
    }

    virtual void Visit(Derived2& d2){
      // handle Derived1
    }
};

int main(){
    Visitor v;
    Derived1 d1;
    d1.Accept(v);
}

The only problem: Now you're missing the chance to have a generic handle to any type of A, since functions can't be both virtual and templates. :|
Scrape that, found a solution using a Superbase base class. :) This even allows you to have a container of Superbases and take full advantage of polymorphism. :)

相关问答

更多
  • 只要您已经知道派生类型, C ++协变返回类型支持将仅适用。 要将基类向下转换为可能的派生类,只需使用dynamic_cast(base_ref)来确定base_ref是否与实际的派生类型匹配: int main () { base* pd = new derived(); derived& x = dynamic_cast(*pd); // Will throw an exception if pd ...
  • 现在你已经向我们展示了你是如何初始化指针的,下面是问题: mitPtr[0] = &angestellter(/*values...*/); 这指向一个临时对象,在声明结束时被销毁。 之后使用指针会导致未定义的行为。 你需要一个非临时变量来指向: angestellter a(/*values...*/); mitPtr[0] = &a; 或者可能是动态分配的对象: mitPtr[0] = new angestellter(...); 在这种情况下,不要忘记删除它; 并且不要忘记给基类一个虚拟析构函数 ...
  • 纯虚函数不仅使基类不可实例化,而且强制所有派生类实现相应的虚函数。 如果您没有将基本函数设为纯虚函数,那么派生类可能会选择不实现它。 正如Scott Meyers所指出的那样,只要从派生实例中使用纯虚函数,就可以定义纯虚函数,并提供可用作默认实现的实现。 请注意,你的演示不像你想象的那样工作。 如果你在使用多态性时通常所做的常见问题, A* p = new B; // or, std::unique_ptr p = make_unique(); p->foo(); 那么你会得到一个讨厌的链接器 ...
  • 您正在分配一个Value_object_data对象,而不是Value_object_uint32 。 您将它转换为Value_object_uint32的事实Value_object_uint32改变任何内容。 实际对象的虚拟表格不知道Value_object_uint32 ; 在其构建于err ...构造时的虚拟函数表中, format指向Value_object_data的format 。 强烈指向指向实际对象的指针类型不能解决问题。 给定层次结构中所有基类和继承类的构造函数都是从派生到根中调用的,每 ...
  • 是的, Derived3有两个vtable指针。 如果您按值访问它,它会使用Derived3版本,或者从父项中选择一个函数,或者表示如果它无法决定它是不明确的。 在孩子的情况下,它使用对应于多态地使用的父1/2的vtable。 请注意,您没有正确使用虚拟继承:我相信Derived1和2应该从Base虚拟继承。 sizeof(Derived3)似乎仍然是8,因为它仍然有两个可能被视为Derived3父母。 当您转换为其中一个父项时,编译器实际上会调整对象指针以获得正确的vtable。 另外我应该指出,任何与v ...
  • 你指的是一种叫做协变回归类型的概念。 由于函数的返回类型不是其签名的一部分,因此只要是指针或引用,就可以在多态方法中返回基类返回类型的派生类型。 在你的情况下,Itriangle的指针(或引用)。 class polygon { public: polygon *translate(class matrix &m) { return new polygon(...); } }; class Itriangle : public matrix, polygon { public ...
  • 这听起来像是一个非常奇怪的约束。 通过各种方式保护用户不被错误使用,但不要试图禁止你只是“看不到”的东西。 如果在没有覆盖任何三个函数的情况下从你的类中派生没有意义,那么让用户覆盖他喜欢的任意数量或更少的函数,并相信他不会做任何无意义的推导而不会覆盖任何一个函数。功能。 用户这样做没有坏处,它不是很有用。 但是如果你确实需要强制执行(再次,我建议你重新考虑),那么不要使用虚函数。 相反,传递函数指针或函数对象(或std::function / boost::function )回调。 使基类看起来像这样: ...
  • 典型: 无论你是否添加peel_me , Apple需要自己的vtable,因为它需要通过Apple实例上的虚拟调用找到它的覆盖display 。 添加peel_me会使vtable中的一个条目大于其他条目 - 与peel_me的代码相比,此附加条目可能会占用或不占用大量空间,但您可能不peel_me 。 Apple的所有派生类的vtable也比没有peel_me 。 Apple实例只有一个vptr。 它指向Apple的vtable。 此表包含Apple所有虚拟成员函数的条目,包括从Fruit继承的函数,包 ...
  • 既然你现在澄清了你想要的是访客模式,那么,对不起,但这就是它的样子。 这个答案显示了双重调度的访问者模式是如何工作的。 我想到了一个使用CRTP的好方法,但根据具体情况,这可能适用于您,也可能不适合您。 (注意:我使用了链接答案中的代码,所以名称不匹配,但我希望你能得到这个想法。) // your Z class Visitor; // superclass needed for generic handling struct Superbase{ virtual void Accept(Visito ...
  • C ++ 11包含final关键字,其中“指定在派生类中不能重写虚拟函数或不能从类继承类”。 1 。 似乎g ++能够在派生类中优化虚函数调用(如果它已被声明为final 。 我创建了以下测试: virtualFunctions.h #pragma once class Base { public: virtual void foo(); virtual void bar(); virtual void baz(); int fooVar, barVar, bazVar; }; class ...

相关文章

更多

最新问答

更多
  • python的访问器方法有哪些
  • 使用Zend Framework 2中的JOIN sql检索数据(Retrieve data using JOIN sql in Zend Framework 2)
  • 透明度错误IE11(Transparency bug IE11)
  • linux的基本操作命令。。。
  • 响应navi重叠h1和nav上的h1链接不起作用(Responsive navi overlaps h1 and navi links on h1 isn't working)
  • 在C中读取文件:“r”和“a +”标志的不同行为(Reading a File in C: different behavior for “r” and “a+” flags)
  • NFC提供什么样的带宽?(What Kind of Bandwidth does NFC Provide?)
  • 元素上的盒子阴影行为(box-shadow behaviour on elements)
  • Laravel检查是否存在记录(Laravel Checking If a Record Exists)
  • 设置base64图像的大小javascript - angularjs(set size of a base64 image javascript - angularjs)
  • 想学Linux 运维 深圳有哪个培训机构好一点
  • 为什么有时不需要在lambda中捕获一个常量变量?(Why is a const variable sometimes not required to be captured in a lambda?)
  • 在Framework 3.5中使用服务器标签<%=%>设置Visible属性(Set Visible property with server tag <%= %> in Framework 3.5)
  • AdoNetAppender中的log4net连接类型无效(log4net connection type invalid in AdoNetAppender)
  • 错误:发送后无法设置标题。(Error: Can't set headers after they are sent. authentication system)
  • 等待EC2实例重启(Wait for an EC2 instance to reboot)
  • 如何在红宝石中使用正则表达式?(How to do this in regex in ruby?)
  • 使用鼠标在OpenGL GLUT中绘制多边形(Draw a polygon in OpenGL GLUT with mouse)
  • 江民杀毒软件的KSysnon.sys模块是什么东西?
  • 处理器在传递到add_xpath()或add_value()时调用了什么顺序?(What order are processors called when passed into add_xpath() or add_value()?)
  • sp_updatestats是否导致SQL Server 2005中无法访问表?(Does sp_updatestats cause tables to be inaccessible in SQL Server 2005?)
  • 如何创建一个可以与持续运行的服务交互的CLI,类似于MySQL的shell?(How to create a CLI that can interact with a continuously running service, similar to MySQL's shell?)
  • AESGCM解密失败的MAC(AESGCM decryption failing with MAC)
  • SQL查询,其中字段不包含$ x(SQL Query Where Field DOES NOT Contain $x)
  • PerSession与PerCall(PerSession vs. PerCall)
  • C#:有两个构造函数的对象:如何限制哪些属性设置在一起?(C#: Object having two constructors: how to limit which properties are set together?)
  • 平衡一个精灵(Balancing a sprite)
  • n2cms Asp.net在“文件”菜单上给出错误(文件管理器)(n2cms Asp.net give error on Files menu (File Manager))
  • Zurb Foundation 4 - 嵌套网格对齐问题(Zurb Foundation 4 - Nested grid alignment issues)
  • 湖北京山哪里有修平板计算机的