小编Jer*_*ner的帖子

有没有自动化的方法来实现post-constructor和pre-destructor虚方法调用?

由于从构造函数和析构函数内部调用虚方法的众所周知的问题,我通常最终会得到一些类,这些类需要在构造函数之后调用最终设置方法,并且在它们之前调用一个预拆解方法析构函数,像这样:

MyObject * obj = new MyObject;
obj->Initialize();   // virtual method call, required after ctor for (obj) to run properly
[...]
obj->AboutToDelete();  // virtual method call, required before dtor for (obj) to clean up properly
delete obj;
Run Code Online (Sandbox Code Playgroud)

这有效,但它带来了调用者在适当的时候忘记调用其中一种或两种方法的风险.

所以问题是:在C++中是否有任何方法可以自动调用这些方法,因此调用者不必记得调用它们?(我猜不会有,但我想我无论如何都会问,以防有一些聪明的方法去做)

c++ methods virtual-destructor

13
推荐指数
2
解决办法
4461
查看次数

可以将无关数据存储在指针的最低有效位中吗?

让我先说一下,我所知道的是我要提出的是一个致命的罪,并且即使考虑它,我也可能会在编程地狱中燃烧.

也就是说,我仍然有兴趣知道为什么这不起作用.

情况是:我有一个我在任何地方使用的引用计数智能指针类.它目前看起来像这样(注意:不完整/简化的伪代码):

class IRefCountable
{
public:
    IRefCountable() : _refCount(0) {}
    virtual ~IRefCountable() {}

    void Ref() {_refCount++;}
    bool Unref() {return (--_refCount==0);}

private:
    unsigned int _refCount;
};

class Ref
{
public:
   Ref(IRefCountable * ptr, bool isObjectOnHeap) : _ptr(ptr), _isObjectOnHeap(isObjectOnHeap) 
   { 
      _ptr->Ref();
   }

   ~Ref() 
   {
      if ((_ptr->Unref())&&(_isObjectOnHeap)) delete _ptr;
   }

private:
   IRefCountable * _ptr;
   bool _isObjectOnHeap;
};
Run Code Online (Sandbox Code Playgroud)

今天我注意到sizeof(Ref)= 16.但是,如果我删除布尔成员变量_isObjectOnHeap,则sizeof(Ref)减少到8.这意味着对于我的程序中的每个Ref,有7.875个浪费的RAM字节......并且我的程序中有很多很多Refs .

好吧,这似乎浪费了一些内存.但我真的需要那些额外的信息(好吧,幽默我,并为了我真正做的讨论而假设).我注意到,由于IRefCountable是一个非POD类,它(可能)总是被分配在一个字对齐的内存地址上.因此,(_ptr)的最低有效位应始终为零.

这让我想知道...有什么理由说我不能将我的一点布尔数据或指针的最低有效位,并因此将sizeof(Ref)减少一半而不牺牲任何功能?当然,在取消引用指针之前,我必须小心取出那个位,这会使指针解引用效率降低,但这可能是因为Refs现在更小,因此更多可以立即适应处理器的缓存,依此类推.

这是合理的事吗?还是我为自己创造了一个受伤的世界?如果是后者,那么伤害到底是怎么回事?(请注意,这是需要在所有合理的现代桌面环境中正确运行的代码,但它不需要在嵌入式计算机或超级计算机或任何异国情况下运行)

c++ bit-manipulation smart-pointers

12
推荐指数
1
解决办法
1016
查看次数

在编译时检测库代码和用户代码之间不匹配的预处理器定义的好技术是什么?

激励背景信息:我维护一个 C++ 库,这个周末我花了太多时间来追踪链接到该库的应用程序中的神秘内存损坏问题。该问题最终被证明是由于 C++ 库是使用特定的-DBLAH_BLAH编译器标志构建的,而应用程序的代码是在没有该-DBLAH_BLAH标志的情况下编译的,这导致库代码和应用程​​序代码解释库的头文件中声明的类在数据布局方面有所不同。也就是说:sizeof(ThisOneParticularClass)从应用程序中的 .cpp 文件调用时返回的值与从库中的 .cpp 文件调用时返回的值不同。

到目前为止,非常不幸 - 我已经通过确保库和应用程序都使用相同的预处理器标志构建来解决了眼前的问题,并且我还修改了库,以便标志的存在或不存在-DBLAH_BLAH不会影响它sizeof()导出的类...但我觉得这并不足以解决使用与使用该库的应用程序不同的预处理器标志编译的库的更普遍的问题。理想情况下,我希望找到一种机制,可以在编译时捕获此类问题,而不是允许它在运行时默默地调用未定义的行为。有没有好的技术可以做到这一点?(我能想到的就是自动生成一个头文件,其中包含#ifdef/#ifndef对应用程序代码的测试#include,如果未设置#error必要的 s,则该头文件会故意排除,或者可能会自动在那里设置适当的 s...但是这感觉很像重新发明和类似,这似乎有可能打开一大堆蠕虫)#define#defineautomake

c++ preprocessor static-libraries

12
推荐指数
3
解决办法
1031
查看次数

为什么MSVC不支持AMD64和Itanium目标的内联汇编?

昨天我了解到,在编译AMD64和Itanium目标时,Microsoft Visual C++不支持内联汇编(使用__asm关键字).

那是对的吗?如果是这样,有谁知道为什么他们不支持这些目标的内联汇编?这似乎是一个相当大的特点,只是放弃......

assembly x86-64 itanium inline-assembly visual-c++

11
推荐指数
2
解决办法
4360
查看次数

如何设置winsock的保持活动间隔

我正在使用winsock和TCP.我已将KeepAlive选项设置如下

int aliveToggle = 1;
setsockopt(mySocket,SOL_SOCKET,SO_KEEPALIVE,(char*)&aliveToggle, sizeof(aliveToggle));
Run Code Online (Sandbox Code Playgroud)

但是如何指定Keep aLive时间和间隔?

我正在使用在Windows 7上运行的VC++.

sockets visual-c++

10
推荐指数
2
解决办法
2万
查看次数

在布尔值上使用按位非运算符(〜)是否会调用未定义的行为?

如果C++程序将bitwise-not运算符(〜)应用于布尔值,那么它是否会调用未定义的行为?

例如,以下程序定义明确吗?

bool f = false;
bool f2 = ~f;    // is f2 guaranteed to be true, or is this UB?
bool t = true;
bool t2 = ~t;    // is t2 guaranteed to be false, or is this UB?
Run Code Online (Sandbox Code Playgroud)

(是的,我知道有一个更适合这类事情的!运算符;出于这个问题的目的,我们将忽略它的存在;))

c++ bit-manipulation undefined-behavior language-lawyer

10
推荐指数
1
解决办法
495
查看次数

当类本身被标记为 [[nodiscard]] 时,将类的构造函数标记为 [[nodiscard]] 有什么好处吗?

假设我有这门课:

class [[nodiscard]] MyClass
{
public:
   MyClass() : _x(x) {}
   MyClass(int x) : _x(x) {}

private:
   int _x;
};
Run Code Online (Sandbox Code Playgroud)

将标签单独添加[[nodiscard]]到类的构造函数中会改变什么吗?或者这对于[[nodiscard]]应用于类声明本身的标签来说是完全多余的,因此只会给头文件添加不必要的噪音?

(我的测试表明后者,但我可能会错过一些细微差别)

c++ c++17 nodiscard c++-attributes

9
推荐指数
1
解决办法
157
查看次数

在编写高带宽数据流时,如何最好地管理Linux的缓冲行为?

我的问题是:我有一个在Linux下运行的C/C++应用程序,这个应用程序接收一个恒定速率的高带宽(约27MB /秒)数据流,它需要流式传输到一个或多个文件.它运行的计算机是运行Linux的四核2GHz Xeon.文件系统是ext4,磁盘是固态E-SATA驱动器,为此目的应该足够快.

问题是Linux过于聪明的缓冲行为.具体来说,不是立即将数据写入磁盘,或者在我调用write()之后不久,Linux会将"写入"数据存储在RAM中,然后在稍后的某个时间(我怀疑当2GB的RAM开始变满时)它会突然尝试同时向磁盘写出几百兆的缓存数据.问题是这个缓存刷新很大,并且在很长一段时间内阻止了数据采集代码,导致一些当前的输入数据丢失.

我的问题是:有没有合理的方法来"调整"Linux的缓存行为,因此要么根本不缓存传出数据,要么它必须缓存,它一次只缓存一个较小的数量,从而平滑驱动器的带宽使用情况和提高代码的性能?

我知道O_DIRECT,并将使用我必须的,但它确实对程序施加了一些行为限制(例如缓冲区必须对齐并且是磁盘扇区大小的倍数等),我宁愿避免,如果我能够.

c c++ linux streaming caching

8
推荐指数
1
解决办法
2949
查看次数

FogBugz基于证据的调度:它在现实世界中的运作情况如何?

我的公司已经使用FogBugz一段时间了,我们通常很高兴它作为一个错误跟踪工具.我一直在阅读Joel Spolsky关于他们的基于证据的调度功能的文章.这在理论上听起来很棒,但我没有看到很多关于它在实践中如何运作的讨论.在我花费大量时间和精力试图说服我的同事购买使用它之前,我想听听那些在开发中使用此功能的人.

你一直在使用FogBugz的EBS吗?如果是这样,你满意吗?它的估计值是否准确到足以提供帮助?事后看来,您是否认为设置它并输入所需的所有信息/估算是值得的?您发现其他一些机制更好吗?

(注意:我故意将此发布到stackoverflow.com而不是fogbugz.stackexchange.com,因为我怀疑fogbugz.stackexchange.com的用户群可能过分偏向于FogBugz - 特别是前Fogbugz已经转向更好的用户不太可能阅读或发布在那里

fogbugz

8
推荐指数
0
解决办法
368
查看次数

是否有减少完全Doxygen覆盖所需的冗余评论量的技巧?

作为记录我的C++代码库的一部分,我正在努力获得完整的Doxygen覆盖 - 也就是说,我希望我的所有(数百个)头文件都为其所有公共API提供格式良好的Doxygen注释,以便我可以在代码库上运行Doxygen而不会看到任何"警告:没有记录的blah"警告.

一般来说,这只是一个记录和记录内容的问题,但我注意到我一直在为每个课程反复输入相同的文本.例如,我有很多基本上这样的实例:

/** The Foo class represents blah blah blah */
class Foo
{
public:
    /** Default constructor */
    Foo();

    /** Copy constructor
      * @param rhs the object to make this object a copy of.
      */
    Foo(const Foo & rhs);

    /** Destructor */
    ~Foo();

    /** Equality operator.
      * @param rhs the object to compare against.
      * @returns true iff this object and (rhs) are equal.
      */
    bool operator == (const Foo & rhs) const;

    /** Inequality operator.
      * …
Run Code Online (Sandbox Code Playgroud)

c++ doxygen

8
推荐指数
1
解决办法
252
查看次数