基于另一个成员参数将函数调用从类传递给它的一个成员
Pass function call from a class to one of its members based on another member parameter
假设我有以下class A
,它通过不同的函数调用和包装器传递。
class A{
std::vector<int> a;
public:
int getSize const {return a.size();}
int getVal(int i) const {return a[i];}
// other private and public members and functions
}
现在出于某种原因,我需要相同的类,但有一个双向量。我无法将此类模板化,因为有许多函数签名我无法更改。建议将A
重命名为A0
,将其模板化,创建包含A0<int>
和A0<double>
的新A
,如下所示:
template <typename T>
class A0{
std::vector<T> a;
public:
int getSize const {return a.size();}
T getVal(int i) const {return a[i];}
// other private and public members and functions
}
class A{
// only one of the following will be initialized in the constructor and the other one will be null.
std::shared_ptr<A0<int>> iA;
std::shared_ptr<A0<double>> dA;
// also the following flag will be set in the constructor
bool isInt;
}
这就是问题:如果我想在以前访问、更改或刚刚传递类A
实例的代码的不同位置进行最小的更改,该怎么办?例如,在旧代码的另一部分中考虑这一点:
A x;
int n = x.getSize();
有没有一种方法可以保留旧代码,而不在新的A
类中实现方法getSize()
,该类将包含if条件语句并基于isInt
返回iA->getSize()
或dA->getSize()
?有聪明的方法吗?
对于在使用(主要是传递(旧A
的代码的不同部分中实现最小修改的目标,还有其他建议吗?
}
如果这只是传递对象(或对它的引用(,而不是实际使用对象的任何成员,那么您可以简单地使用std::variant
:
using A = std::variant<A0<int>, A0<double>>;
在实际使用成员的点上,使用std::visit
来确定类型并对其执行操作
如果传递仅通过引用发生,则使A
成为A0<T>
的空基类也将起作用。然后,您可以使用static_cast<A0<int>&>(...)
或static_cast<A0<double>&>(...)
强制转换回真实类型,以使用目的地的成员。但是,必须确保强制转换为传递对象的实际类型,否则将有未定义的行为。
另一种选择是dynamic_cast
而不是static_cast
,如果类型不匹配,它将抛出或返回一个空指针。但这需要基类A
有一个虚拟方法来实现多态性。
std::variant
可能就是您所需要的。创建一个buffer
类并将所有容器操作转发给它。在A
类中不需要更改太多,但应该在buffer
中模仿std::vector<T>
,我实现了size()
和const subscript operator
。以下是基本演示。
#include <variant>
#include <vector>
#include <iostream>
struct store_as_int {};
struct store_as_double {};
class buffer {
public:
buffer( store_as_int ) : data { std::vector<int>{} } {
std::cout << "I am storing numbers as int" << std::endl;
}
buffer( store_as_double ) : data { std::vector<double>{} } {
std::cout << "I am storing numbers as double" << std::endl;
}
[[nodiscard]] std::size_t size() const noexcept {
std::size_t s;
std::visit( [ &s ]( auto&& arg ) {
s = arg.size();
} , data );
return s;
}
[[nodiscard]] double operator[]( std::size_t idx ) const {
double s;
std::visit( [ &s , idx ]( auto&& arg ) {
s = arg[ idx ];
} , data );
return s;
}
private:
std::variant< std::vector<int> , std::vector<double> > data;
};
class A{
buffer a;
public:
A() : a { store_as_int{} } {}
A( store_as_double ) : a { store_as_double {} } { }
int getSize() const { return a.size(); }
int getVal(int i) const { return a[i]; }
};
int main()
{
A x;
A y { store_as_double{} };
int n = x.getSize();
int t = x.getSize();
std::cout << n << std::endl;
std::cout << t << std::endl;
}
输出:
我将数字存储为int
我将数据存储为double
0
0
运行在线
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 我们可以访问一个不存在的联盟的成员吗
- 为什么我不能在一个类的不同行中声明和定义成员变量?
- 我不小心调用了一个没有自己类对象的成员函数.但这是怎么回事呢
- 如何从另一个文件继承私有成员变量和公共函数
- C++-我可以创建另一个类的成员并在构造函数中使用它吗
- 是否可以同时声明一个类成员的常量/非常量?
- int数据类型的指针指向的是什么,如果是一个类的私有数据成员,我们创建了该类的两个对象?
- 在作为静态成员包含在另一个类中的类的构造函数中使用 cout
- 为什么将一个结构的引用设置为等于另一个结构只会更改一个数据成员?
- 我有一个对象,它将在整个程序的持续时间内实例化,但一个类成员不会,我应该动态分配它吗?
- C++ - 如何在结构向量中找到结构体一个成员的最大值?
- 如何定义一个没有重复代码的继承的 const 类成员函数?
- 没有公共构造函数作为另一个类模板成员的类模板
- 将另一个类的对象传递到当前类C++的构造函数中(不是成员初始化)
- 在 C++ 中声明 const 对象需要用户定义的默认构造函数.如果我有一个可变成员变量,为什么不呢?
- 将类成员函数作为线程调用到另一个类成员函数时发出警告消息
- 如何使用另一个类中的公共成员函数作为参数调用线程
- 访问超类类型成员对象的受保护成员 - 一个优雅的解决方案