gpt4 book ai didi

c++ - 在 C++ 中,我怎样才能从一个对象到一个静态成员?

转载 作者:行者123 更新时间:2023-11-28 02:51:55 24 4
gpt4 key购买 nike

所以我有以下问题:

假设我有一个名为 Shape 的基类声明如下:

class Shape
{
public:
virtual void output(std::ostream &) const = 0;
}

Shape 派生了一些类,比如矩形和三角形。这些类有一个名为 identifier 的静态成员,如下例所示:

class Rectangle: public Shape
{
public:
static const std::string identifier;
}

现在有另一个类实现了一个指向形状组的指针 vector

class Group : public Shape
{
private:
std::vector<Shape *> continut;
public:
static const std::string identifier;
void output(std::ostream &) const;
}

现在我的问题是如何为组实现读写。

我已经为三角形和矩形实现了 >> 和 << 运算符,我想到的想法是使用标识符来确定对象类型,问题是标识符是静态的,所以我想知道在这种情况下我可以做到。

欢迎任何帮助。谢谢。

最佳答案

通常,如果你想做一个动态调度的操作,你必须使用虚函数。

class Shape
{
virtual ~Shape() {} //ALWAYS HAVE THIS IF YOU HAVE VIRTUAL FUNCTIONS
virtual void read(std::istream&) =0;
virtual void write(std::ostream&) const =0;
public:
virtual void output(std::ostream &) const = 0;

friend std::istream& operator>>(std::istream& in, Shape& sh)
{sh->read(in); return in;}
friend std::ostream& operator<<(std::ostream& out, const Shape& sh)
{sh->write(out); return out;}
};

class Rectangle: public Shape
{
virtual void read(std::istream&);
virtual void write(std::ostream&);
public:
static const std::string identifier;
//does not need (and probably should not have) `operator>>` and `operator<<`.
};

class Group : public Shape
{
virtual void read(std::istream&);
virtual void write(std::ostream&);
private:
std::vector<Shape*> continut;
public:
static const std::string identifier;
void output(std::ostream &) const;
//does not need (and probably should not have) `operator>>` and `operator<<`.
}

然后在实现中:

void Group::write(std::ostream& out) 
{
//simply calls write for each shape with no separator
//you might want a separator
for(Shape* p : continut)
p->write(out);
}

void Group::read(std::istream& in)
{
//read is far more complicated
//but without knowing the IO format, I can't really help you much.
}

如果你想要一个简单的实现,也许像这样?

void Group::read(std::istream& in) 
{
std::string shapename;
while(in >> shapename)
{
Shape* newshape = null;
if (in == "triangle")
newshape = new triangle();
else if (in == "square")
newshape = new square();
else if (in == "rectangle")
newshape = new rectangle();
else
throw std::runtime_error(in + " is not a known shape!");

newshape->read(in);
continut.push_back(newshape);
}
}

如果您想要更具可扩展性的答案,则需要进行一些调整。

class Shape
{
virtual ~Shape() {} //ALWAYS HAVE THIS IF YOU HAVE VIRTUAL FUNCTIONS
virtual void read(std::istream&) =0;
virtual void write(std::ostream&) const =0;
//this stores functionoids that create the different shape types
typedef std::function<shape*(std::istream&)> named_ctor;
std::unordered_map<std::string, named_ctor> virtual_constructors;
public:
bool register_type(std::string name, named_ctor func)
{constructors[std::move(name)] = std::move(func); return true;}

virtual void output(std::ostream &) const = 0;

friend std::istream& operator>>(std::istream& in, Shape& sh)
{sh->read(in); return in;}
friend std::ostream& operator<<(std::ostream& out, const Shape& sh)
{sh->write(out); return out;}
};

class Rectangle: public Shape
{
virtual void read(std::istream&);
virtual void write(std::ostream&);
static shape* from_stream(std::ostream& in) {
shape s = new Rectangle();
s->read(in);
return s;
};
static const bool registered = register("Rectangle", from_stream);
public:
static const std::string identifier;
//does not need (and probably should not have) `operator>>` and `operator<<`.
};
class Group : public Shape
{
virtual void read(std::istream&);
virtual void write(std::ostream&);

static shape* from_stream(std::ostream& in) {
shape s = new Group();
s->read(in);
return s;
};
static const bool registered = register("Group", from_stream);

std::vector<Shape*> continut;
public:
static const std::string identifier;
void output(std::ostream &) const;
//does not need (and probably should not have) `operator>>` and `operator<<`.
}

然后实现就变成了

void Group::read(std::istream& in) 
{
std::string shapename;
std::vector<Shape*> temp;
while(in >> shapename)
{
auto it = virtual_constructors.find(shapename);
if (it == virtual_constructors.end())
throw std::runtime_error(in + " is not a known shape!");

named_ctor& ctor = it->second;
Shape* newshape = ctor(in);
temp.push_back(newshape);
}
continuit = std::move(temp); //one step closer toward exception safety
}

关于c++ - 在 C++ 中,我怎样才能从一个对象到一个静态成员?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22847584/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com