gpt4 book ai didi

C++,合适的数据模型,多态性

转载 作者:行者123 更新时间:2023-11-28 05:37:54 25 4
gpt4 key购买 nike

我正在寻找合适的数据模型。假设 A 是一个具有属性 a 的类,具有简单的计算方法 getat():

class A{       
protected:
int a;
public:
int getat(int t){return f(a,t);} //Some calculation
virtual int getbt(int t)=0; //b defined in B, C
virtual int getct(int t)=0; //c defined in C
virtual ~A()=0;
};

类推,B、C是属性为b、c的派生类(但C不是B的一种):

class B{       
protected:
int b;
public:
virtual int getbt(int t){return f(b,t);} //Some calculation
virtual int getct(int t){return f(b,t)};
virtual ~B(){};
};

class C{
protected:
int b, c;
public:
virtual int getbt(int t){return f(b,t)};
virtual int getct(int t){return g(c,t)};
virtual ~C(){};
};

考虑到多态性,我想使用父类 A 的存储对象:

std::list <A>;   //Abstract class, impossible
std::list <A*>; //Possible, but problem with the destructors
std::list<std::shared_ptr<A> >; //The best solution?

我的问题:

1] 提出的纯虚函数数据模型是否合理?

2] 去除抽象有意义吗?

class A{       
protected:
int a;
public:
int getat(int t){return f(a,t);}
int getbt(int t){};
int getct(int t){};
}

随后,允许使用 std::list。

3] 如果需要多态性,建议使用哪种存储 A 对象的方法?

感谢您的帮助...

最佳答案

嗯……作文怎么样?

为了完整起见,我已经使句柄可复制

#include <utility>
#include <memory>
#include <vector>
#include <iostream>

int f(int a, int t) {
return a * t;
}

struct has_a
{
int a;
};

/// when some T is not derived from has_a, its getat method will return 0
template<class T, std::enable_if_t<not std::is_base_of<has_a, T>::value>* = nullptr>
int impl_getat(const T&, int t) { return 0; }

// when some T is derived from has_a, its getat method will return f(a, t)
template<class T, std::enable_if_t<std::is_base_of<has_a, T>::value>* = nullptr>
int impl_getat(const T& a, int t) { return f(a.a, t); }

// ditto for has_b
struct has_b
{
int b;
};
template<class T, std::enable_if_t<not std::is_base_of<has_b, T>::value>* = nullptr>
int impl_getbt(const T&, int t) { return 0; }
template<class T, std::enable_if_t<std::is_base_of<has_b, T>::value>* = nullptr>
int impl_getbt(const T& b, int t) { return f(b.b, t); }

// ditto for has_c
struct has_c
{
int c;
};
template<class T, std::enable_if_t<not std::is_base_of<has_c, T>::value>* = nullptr>
int impl_getct(const T&, int t) { return 0; }
template<class T, std::enable_if_t<std::is_base_of<has_c, T>::value>* = nullptr>
int impl_getct(const T& c, int t) { return f(c.c, t); }

// an object to hold the polymorphic model
struct handle
{
// the concept that defines the operations on the model
struct concept {
// rule of 5 when virtual destructors are involved...
concept() = default;
concept(const concept&) = default;
concept(concept&&) = default;
concept& operator=(const concept&) = default;
concept& operator=(concept&&) = default;
virtual ~concept() = default;

// cloneable concept
virtual std::unique_ptr<concept> clone() const = 0;

// concept's interface
virtual int getat(int t) = 0;
virtual int getbt(int t) = 0;
virtual int getct(int t) = 0;
};

// a model models the concept, by deriving from any number of discrete parts
template<class...Parts>
struct model : concept, Parts...
{
model(Parts...parts)
: Parts(std::move(parts))...
{}

model(const model&) = default;

// model the clone op
std::unique_ptr<concept> clone() const override {
return std::make_unique<model>(*this);
}

// defer to impl functions (see above) for the calculations
int getat(int t) override { return impl_getat(*this, t); }
int getbt(int t) override { return impl_getbt(*this, t); }
int getct(int t) override { return impl_getct(*this, t); }
};


std::unique_ptr<concept> _impl;

// interface - note: not polymorphic, so we can be stored in a container
int getat(int t) { return _impl->getat(t); }
int getbt(int t) { return _impl->getbt(t); }
int getct(int t) { return _impl->getct(t); }

// constructor - construct from parts
template<class...Parts>
handle(Parts...parts)
: _impl(std::make_unique<model<std::decay_t<Parts>...>>(std::move(parts)...))
{
}

// let's make it copyable

handle(const handle& r)
: _impl(r._impl->clone())
{
}
// rule of 5 because we meddled with the copy constructor...

handle(handle&& r) : _impl(std::move(r._impl)) {}

handle& operator=(const handle& r) {
_impl = r._impl->clone();
return *this;
}

handle& operator=(handle&& r) = default;


};

int main()
{
std::vector<handle> v;
v.emplace_back(has_a{10}, has_b{12});
v.emplace_back(has_a{1}, has_b{2}, has_c {3});

int aa = 1;
for (auto& x : v)
{
std::cout << x.getat(aa) << std::endl;
std::cout << x.getbt(aa) << std::endl;
std::cout << x.getct(aa) << std::endl;
std::cout << std::endl;
++aa;
}

// prove it's copyable etc

auto y = v.back();
std::cout << y.getat(aa) << std::endl;
std::cout << y.getbt(aa) << std::endl;
std::cout << y.getct(aa++) << std::endl;
std::cout << std::endl;

// and moveable

y = handle(has_a{4}, has_b{5}, has_c{6});
std::cout << y.getat(aa) << std::endl;
std::cout << y.getbt(aa) << std::endl;
std::cout << y.getct(aa++) << std::endl;
std::cout << std::endl;

}

预期结果:

10
12
0

2
4
6

3
6
9

16
20
24

关于C++,合适的数据模型,多态性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37821710/

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