gpt4 book ai didi

c++ - C++:如何实现多态对象创建器来填充表

转载 作者:行者123 更新时间:2023-12-02 10:27:23 25 4
gpt4 key购买 nike

我有一个表小部件对象,可以用set_num_col(int)set_num_row(int)调整大小。
对这些函数中的每一个的调用将调用resize_table()函数,以用table_cell的对象填充小部件。
但是,我有两种多态类型的单元格:table_cell_defaulttable_cell_custom,它们是从同一基类派生的。
创建表后,考虑到客户端知道哪些单元格是自定义的,哪些单元格为默认类型,我如何用混合类型的单元格填充表?
我曾考虑过在表类中添加一个映射,并使用set_custom_cells( vector<index>() )填充此映射,其中单元格的ij索引作为键,相应的lamda创建者返回正确的类型作为值,但是此映射将仅用于一次填充表格,再也不会填充。有没有更动态的方法,将lambda用作table_cell创建器以更好的方式填充该小部件?
谢谢

最佳答案

这是一个使用工厂lambda在Table的构造函数中产生初始单元格的示例。请参阅lambda所在的main函数,以及如何使用它的Table构造函数。
我不知道您的代码是什么样子,因此我只将每个单元格包装到一个object_t中,然后将其放入表中。

#include <cstdint>
#include <functional>
#include <iostream>
#include <memory>
#include <sstream>
#include <string>
#include <vector>

// Not idempotent. Should be last include.
#include <cassert>

using std::cout;
using std::function;
using std::make_shared;
using std::move;
using std::ostream;
using std::shared_ptr;
using std::size_t;
using std::string;
using std::stringstream;
using std::vector;

namespace {

template <typename T>
void draw_right_justified(T const& x, ostream& out, size_t width) {
stringstream ss;
ss << x;
string s = ss.str();
size_t pad_width = s.length() < width ? width - s.length() : 1;
out << string(pad_width, ' ') << s;
}

class object_t {
public:
template <typename T>
object_t(T x) : self_{make_shared<model<T>>(move(x))}
{ }

friend void draw_right_justified(object_t const& x, ostream& out, size_t width) {
x.self_->draw_right_justified_thunk(out, width);
}

private:
struct concept_t {
virtual ~concept_t() = default;
virtual void draw_right_justified_thunk(ostream&, size_t) const = 0;
};

template <typename T>
struct model : concept_t {
model(T x) : data_{move(x)} { }

void draw_right_justified_thunk(ostream& out, size_t width) const {
draw_right_justified(data_, out, width);
}

T data_;
};

shared_ptr<const concept_t> self_;
};

class Table {
size_t col;
size_t row;
// data will be constructed with col_ * row_ entries.
vector<object_t> data;
public:
using object_factory = function<object_t(size_t, size_t)>;
Table(size_t col_, size_t row_, object_factory& fn);
auto operator()(size_t x, size_t y) const -> object_t;
void display(ostream& out) const;
};

Table::Table(size_t col_, size_t row_, Table::object_factory& fn)
: col{col_}, row{row_}
{
data.reserve(col * row);
for (size_t y = 0; y < row; ++y) {
for (size_t x = 0; x < row; ++x) {
data.emplace_back(fn(x, y));
}
}
}

object_t Table::operator()(size_t x, size_t y) const {
assert(x < col);
assert(y < row);
return data[y * row + x];
}

void Table::display(ostream& out) const {
auto const& self = *this;
for (size_t y = 0; y < row; ++y) {
for (size_t x = 0; x < col; ++x) {
draw_right_justified(self(x, y), out, 8);
}
out << "\n";
}
}

struct empty_t {};

void draw_right_justified(empty_t, ostream& out, size_t width) {
string s = "(empty)";
size_t pad_width = s.length() < width ? width - s.length() : 1;
out << string(pad_width, ' ') << s;
}

struct bunny { string name; };

void draw_right_justified(bunny const& bunny, ostream& out, size_t width) {
auto const& s = bunny.name;
size_t pad_width = s.length() < width ? width - s.length() : 1;
out << string(pad_width, ' ') << s;
}

} // anon

int main() {
Table::object_factory maker = [](size_t x, size_t y) {
if (x == 0 && y == 1) return object_t{bunny{"Bugs"}};
if (x == 0 && y == 0) return object_t{empty_t{}};
if (x == y) return object_t{string("EQUAL")};
return object_t{x * y};
};

auto table = Table{3, 5, maker};
table.display(cout);
}
输出...
 (empty)       0       0
Bugs EQUAL 2
0 2 EQUAL
0 3 6
0 4 8

关于c++ - C++:如何实现多态对象创建器来填充表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63742112/

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