我的模板类中是否可以有一个静态成员变量,而该类的用户不必知道它?

2024-01-08

我有一个模板化容器类,类似于这个玩具代码:

template <class ItemType> class MyVector
{
public:
   MyVector() : _numItems(0), _items(NULL) {/* empty */}

   /** Returns a reference to the first item in our array,
     * or a default-constructed item if the array is empty.
     */
   const ItemType & GetFirstItemWithDefault() const
   {
      return (_numItems > 0) ? _items[0] : _defaultItem;
   }

   [other methods omitted because they aren't relevant]

private:
   int _numItems;       // how many valid items (_items) points to
   ItemType * _items;   // demand-allocated
   const ItemType _defaultItem;
};

这个类使用起来确实很方便——任何代码都可以只#include“MyVector.h”,然后开始声明 MyVector 和 MyVector 等类型的对象,这一切都可以正常工作(tm),不需要任何麻烦。

然而,让我困扰的一件事是 _defaultItem 成员变量的存在,它的存在只是为了让 GetFirstItemWithDefault() 能够在容器为空时返回有效引用。反对意见是,如果我声明 N 个 MyVector 对象,这意味着 RAM 中也会存在 _defaultItem 的 N 个副本 --- 即使它们都是相同的且只读,因此实际上每个只需要其中一个进程,不是每个 MyVector 都有一个进程。

因此,显而易见的解决方案是使 _defaultItem 静态......但 AFAICT 会带来成本:如果我这样做,任何旧代码都不再可能简单地#include“MyVector.h”并继续。 .. 现在用户必须确保在他的一个 .cpp 文件中声明该静态变量的存储,这(a)是一件令人头疼的事情,(b)意味着代码的用户必须意识到类的内部实现的细节。由于 _defaultItem 是一个私有成员变量,所以该类的用户不必考虑它,甚至不必意识到它的存在,更不用说知道他需要为其声明存储空间。 (如果两段独立的代码都声明了它的存储空间,而彼此不知道对方做了同样的事情,会怎么样?这不会导致重复符号链接器错误吗?)

因此,我的问题是:有没有办法告诉 C++ 自动为这个静态成员变量提供一个唯一的存储(每个 MyVector 的实例化类型),以便 MyVector 的用户不必知道它? (请注意,对于 MyVector<...> 的所有可能实例化,它需要是自动的,而不仅仅是对于一些常见情况)


为什么不将该默认项设为该函数的静态本地项?

const ItemType & GetFirstItemWithDefault() const
{
    static const ItemType _default;
    return (_numItems > 0) ? _items[0] : _default;
}

如果您想再次检查其他函数中的默认项,这可能不是您想要的,但为此您也可以将其放入单独的函数中(本身可能是静态的):

static const ItemType& GetDefault() const
{
  static const ItemType _default;
  return _default;
}

当您需要访问默认项目时调用该函数。


也就是说,我认为拥有默认项目并不是很好。std::vector也没有并且不需要它。只需告诉用户检查向量是否为empty并完成。隐藏静态的一个问题是,你不知道ItemType。它可能是一个消耗大量资源的类,而您刚刚创建了另一个实例!也许重新考虑该类的设计,然后切换到std::vector. :)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

我的模板类中是否可以有一个静态成员变量,而该类的用户不必知道它? 的相关文章

  • 数据模板绑定垃圾邮件输出窗口出现错误:找不到管理 FrameworkElemen

    我有问题 System Windows Data 错误 2 找不到目标元素的管理 FrameworkElement 或 FrameworkContentElement BindingExpression 无路径 数据项 空 目标元素是 So
  • 使用 mono/nunit-console/4 在 Mac OS X 控制台上运行测试

    我安装了 Max OS X 10 11 1 上面装有 Xamarin 我编写了简单的测试类 只是为了测试在 Mac OS X 和 Ubuntu 上运行 Nunit 测试 该类实际上有一个返回字符串的方法 using System names
  • QCombobox 向下箭头图像

    如何更改Qcombobox向下箭头图像 现在我正在使用这个 QSS 代码 但这不起作用 我无法删除向下箭头边框 QComboBox border 0px QComboBox down arrow border 0px background
  • 我如何理解这个 C 类型声明?

    double bar int double double double double 在查看讲座幻灯片时 我发现了留给学生的练习 用简单的英语来说 什么是类型bar在这个 C 声明中 Please帮助我解决这个问题 我什至不知道从哪里开始
  • 使用 Enumerable.OfType() 或 LINQ 查找特定类型的所有子控件

    Existed MyControl1 Controls OfType
  • 如何在 C# / .NET 中创建内存泄漏[重复]

    这个问题在这里已经有答案了 可能的重复 托管代码中是否可能存在内存泄漏 特别是 C 3 0 https stackoverflow com questions 6436620 is it possible to have a memory
  • 根据 N 个值中最小的一个返回不同的结果

    不确定如何使标题更具描述性 所以我只是从一个例子开始 我使用下面的代码位 它从枚举中选择一个方向 具体取决于四个轴中哪一个与给定方向相比形成最小角度 static Direction VectorToDirection Vector2 di
  • 类特定的新删除运算符是否必须声明为静态

    标准中是否要求类特定的 new new delete 和 delete 是静态的 我可以让它们成为非静态成员运算符吗 为什么需要它们是静态的 它们被隐式声明为静态 即使您没有键入 static
  • 类的成员复制

    在学习 复制成员 概念时 书中给出了如下说法 此外 如果非静态成员是引用 const 或没有复制赋值的用户定义类型 则无法生成默认赋值 我不太明白这个声明到底想传达什么 或者说这个说法指的是哪一种场景 谢谢 该语句与编译器自动为您编写的类
  • 如何获取 QTableView 的标题列表?

    我有一个QTableView我的对话框中的对象 我需要访问该表的水平标题并将它们放入QStringList object 尽管进行了大量搜索 但我在 Qt 文档中找不到如何获取此标头列表 编辑 我发现的最接近的地方是this https w
  • C++ php 和静态库

    我创建了一个library a 其中包含 cpp 和 h 文件 其中包含很多类 嵌套类和方法 我想在 php 示例中包含这个静态库并尝试使用它 我想提一下 我是 php 新手 我已经在 test cpp 文件中测试了我的 libray a
  • AES 输出是否小于输入?

    我想加密一个字符串并将其嵌入到 URL 中 因此我想确保加密的输出不大于输入 AES 是可行的方法吗 不可能创建任何始终会创建比输入更小的输出的算法 但可以将任何输出反转回输入 如果您允许 不大于输入 那么基本上您只是在谈论同构算法alwa
  • 如何在c的case语句中使用省略号?

    CASE expr no commas ELLIPSIS expr no commas 我在c的语法规则中看到了这样的规则 但是当我尝试重现它时 int test float i switch i case 1 3 printf hi 它失
  • 在 EnvDTE 中调试时捕获 VS 局部变量

    是否可以使用 EnvDTE 进行 vsix Visual Studio 扩展来捕获本地和调试窗口使用的调试数据 或者可以通过其他方法吗 我想创建一个自定义的本地窗口 我们可以修改它以根据需要显示一些较重的内容 而无需为高级用户牺牲原始的本地
  • 使用restsharp序列化对象并将其传递给WebApi而不是序列化列表

    我有一个看起来像的视图模型 public class StoreItemViewModel public Guid ItemId get set public List
  • cout 和字符串连接

    我刚刚复习了我的 C 我尝试这样做 include
  • C++ Streambuf 方法可以抛出异常吗?

    我正在尝试找到一种方法来获取读取或写入流的字符数 即使存在错误并且读 写结束时间较短 该方法也是可靠的 我正在做这样的事情 return stream rdbuf gt sputn buffer buffer size 但如果streamb
  • 矩阵到数组 C#

    这将是转换方阵的最有效方法 例如 1 2 3 4 5 6 7 8 9 into 1 2 3 4 5 6 7 8 9 in c 我在做 int array2D new int 1 2 3 4 5 6 7 8 9 int array1D new
  • 从 JavaScript 中的 OnClientClick 事件中阻止 C# 中的 asp:Button OnClick 事件?

    我有一个asp Button在我的网页上 它调用 JavaScript 函数和代码隐藏方法 后者进行调用以导航到另一个页面 在 JavaScript 函数中 我正在检查条件 如果不满足这个条件 我想中止导航 以便OnClick方法未被调用
  • Java 和/C++ 在多线程方面的差异

    我读过一些提示 多线程实现很大程度上取决于您正在使用的目标操作系统 操作系统最终提供了多线程能力 比如Linux有POSIX标准实现 而windows32有另一种方式 但我想知道编程语言水平的主要不同 C似乎为同步提供了更多选择 例如互斥锁

随机推荐