xcode c++错误:分配抽象类类型'Grain'的对象

Posted

技术标签:

【中文标题】xcode c++错误:分配抽象类类型\'Grain\'的对象【英文标题】:xcode c++ error: allocating an object of abstract class type 'Grain'xcode c++错误:分配抽象类类型'Grain'的对象 【发布时间】:2017-05-08 18:13:58 【问题描述】:

这是发生错误的方法。 这里的目标是在给定的小时间增量 dt 的基础上,根据模型颗粒(modele)生成一定数量的沙粒。 Grain 是一个抽象类,因为它具有纯虚方法,而且必须是这样。 问题出现在

for(size_t a(0); a<vect.size(); ++a)
    vect[a] = new Grain(*modele);

没有这个初始化循环,向量返回所有相同的颗粒,但我需要它们稍微不同(Aleatoire 类为此提供了必要的工具)。 例如,如果我这样做

for(size_t a(0); a<vect.size(); ++a)
    vect[a] = modele;

错误消失但返回的向量包含所有相同的颗粒,它们都是设置循环中的最后一个颗粒

std::vector<Grain*> Source::creation( std::vector<Grain*> grains, double dt)
vector<Grain*> vect; //vide par defaut

Aleatoire generateur(1);

//determiner nombre de grains a generer: DEBUT ALGO
double fraction = debit*dt; // fraction = debit "vrai", mais a priori non entier
int nombre(fraction);      // partie entière
fraction -= nombre;        // partie fractionnaire
// on ajoute 1 au hasard, proportionnellement à la partie fractionnaire :
if ( generateur.uniforme(0.0, 1.0) < fraction ) ++nombre;
//---FIN ALGO---
cout<<"Pour un pas de temps "<<dt<<" on genere "<<nombre<<" grains."<<endl;

double x, y, z, r;
vect.resize(nombre, nullptr);

for(size_t a(0); a<vect.size(); ++a)
    vect[a] = new Grain(*modele);

cout<< "APRES LA FONCTION RESIZE, la taille du tableau est : "<<vect.size()<<endl;

for(size_t i(0); i<nombre; ++i)
    (vect[i])->setPosition(position); //Le grain genere est genere a la position de la source
    x = generateur.gaussienne(vitesse_iMoyenne.getCoord_x(), ecart_typeVitesse);
//        cout<<"x = "<<setw(2)<<x<<" ";
    y = generateur.gaussienne(vitesse_iMoyenne.getCoord_y(), ecart_typeVitesse);
//        cout<<"y = "<<setw(2)<<y<<" ";
    z = generateur.gaussienne(vitesse_iMoyenne.getCoord_z(), ecart_typeVitesse);
//        cout<<"z = "<<setw(2)<<z<<" ";
    Vecteur3D v(x,y,z);
//        cout<<"Le nouveau vecteur vitesse est : "<<setw(2)<<v<<" "<<endl;
    vect[i]->setVitesse(Vecteur3D(x,y,z));
//        cout<<"Le vecteur vitesse copie est : "<<setw(2)<<vect[i]->getVitesse()<<" "<<endl;

    r = generateur.gaussienne(modele->getRayon(), ecart_typeRayon);
//        cout<<"Le nouveau rayon est : "<<setw(2)<<r<<" "<<endl;
    vect[i]->setRayon(abs(r));
//        cout<<"Le rayon copie est : "<<vect[i]->getRayon()<<" "<<endl;

//        cout<<"Affichage dans la methode, dans la boucle for : "<<endl;
//        cout<<setw(2)<<i<<" "<<*(vect[i])<<endl;
//        cout<<endl;


//    cout<<"Affichage dans la methode du vecteur de grains generes : "<<endl;
//    for(size_t j(0); j<vect.size(); ++j)
//        cout<<setw(2)<<j<<" "<<*(vect[j])<<endl;
//    
//    cout<<endl;
return vect;  

这是 Grain.hpp:

#ifndef Grain_hpp
#define Grain_hpp
#include "Vecteur3D.hpp"
#include "Dessinable.hpp"

class Grain : public Dessinable 
public:
Grain(Vecteur3D p=0.0,0.0,0.0, Vecteur3D v=0.0,0.0,0.0, double m =             1.0, double r = 1.0, Vecteur3D f = 0.0,0.0,0.0, SupportADessin* support = nullptr );

virtual ~Grain();

double masse() const;

//eta_milieu est la constante de viscosite du milieu

double lambda() const; //coef de frottement fluide

void ajouteForce();

void bouger(double pas);

virtual void affiche(std::ostream& sortie) const ;

void setVitesse(Vecteur3D const& v);

void setPosition(Vecteur3D const& p);

void setRayon(double const& r);

Vecteur3D getPosition() const;

double getRayon() const;

Vecteur3D getVitesse() const;

Vecteur3D calcule_force() const;

virtual Vecteur3D* vecteurForce(Grain* grain) const =0;



//Methodes forces virtuelles

virtual void ajouteForce(Obstacle* obstacle) = 0;

virtual void ajouteForce(Grain* grain) = 0;

virtual void ajouteForce(Vecteur3D) = 0;

//Dessinable


Grain(SupportADessin* vue)
: Dessinable(vue)


virtual void dessine() override;

protected:

Vecteur3D position;

Vecteur3D vitesse;

double m_volumique;

double rayon;

Vecteur3D force;

;
std::ostream& operator<<(std::ostream& sortie, Grain const& g) ;
#endif /* Grain_hpp */

【问题讨论】:

为什么Grain里面有纯虚函数? 如果不是不言自明的错误,那也不算什么。 Grain 是一个抽象类。您的纯虚拟会员巩固了这种地位。所以...不要再尝试制作 say-same 的具体实例了。 感谢@WhozCraig 的评论。好吧,我知道我无法创建抽象类的具体实例,但在这里我只是创建了一个指针。没有什么禁止对可能不同但属于同一个超类的对象进行异构集合。就像后来可以成为飞机、汽车、潜艇等的车辆集合。 @StanislasHildebrandt new Grain(*modele); 创建它的具体实例。 谢谢@AlgirdasPreidžius 我不确定,我认为保留字“new”返回了一个指向 wathever 的指针,这里是否可以使用替代方法? 【参考方案1】:

在您的情况下,您似乎想要克隆现有对象。如果您知道要复制的对象的类型,您将使用复制构造函数。假设以下抽象基类和它的具体子类:

class AbstractBase 
public:
    virtual void print() = 0;
;

class ConcreteClass : public AbstractBase 
public:
    ConcreteClass(int initVal) : testVal(initVal) ;
    virtual void print()  cout << "ConcreteClass with testVal " << testVal << endl; 
    int testVal;
;

int main()     
    ConcreteClass *cObj = new ConcreteClass(5);
    AbstractBase* copyOfCObj = new ConcreteClass(*cObj);
    copyOfCObj->print(); // output: ConcreteClass with testVal 5
    return 0;

请注意,代码没有指定单独的复制构造函数,因此编译器将生成一个默认的复制构造函数(它实际上克隆了所有数据成员)。如果这还不够,请定义自己的复制构造函数;但这是一个单独的主题。

如果您不知道要克隆的对象的具体类型(例如,因为您只有一个指向它的指针,并且该指针在其他地方分配了一个对象),那么一些自定义代码是必要的(参见,例如,Copying a Polymorphic object in C++)。 C++ 确实——据我所知——不提供内置的“克隆”功能,除非你知道这个对象的具体类型;所以你必须提供你自己的“克隆”功能,它会带来这种类型的信息:

class AbstractBase 
public:
    virtual AbstractBase* clone() = 0;
    virtual void print() = 0;
;

class ConcreteClass : public AbstractBase 
public:
    ConcreteClass(int initVal) : testVal(initVal) ;

    virtual ConcreteClass* clone() 
        return new ConcreteClass(*this);
    

    virtual void print()  cout << "ConcreteClass with testVal " << testVal << endl; 

    int testVal;
;

int main() 
    AbstractBase* modele = new ConcreteClass(10);
    AbstractBase* copyOfModele = modele->clone();
    copyOfModele->print(); // output: ConcreteClass with testVal 10
    return 0;

【讨论】:

感谢您的回答,不幸的是,如果可能的话,我想做的事情是一个也适用于抽象对象的 clone() 方法。方法 creation() 正在根据抽象对象的模型创建指向抽象对象的指针向量,因此抽象对象的副本或克隆......我不知道我想要做的是可能,如果不是,我可能会考虑使这个方法特定于某个具体的子对象。但问题是,创建必须能够根据 Grains 的不同子对象创建 Grains 的向量...... 你无法实现抽象类的实例,无论是通过复制、克隆还是通过其他方式尝试创建它。您可以只创建具体对象,尽管AbstractClass* 类型的指针可能指向它们。请注意,即使AbstractClass* 类型的(多态)指针指向它,对象本身仍将是具体的。

以上是关于xcode c++错误:分配抽象类类型'Grain'的对象的主要内容,如果未能解决你的问题,请参考以下文章

新类型(抽象类)

silo 主机 报找不到 grain 实现错误的一个注意

Java抽象类

Java抽象类

在 TypeScript 中为具有类型变量的抽象类中的派生类分配泛型类型

如何使用抽象类型的 C++ 指针指向具体类?