我需要一个类在其对象的生命周期内将一个ostream重定向到另一个ostream.经过一些修修补补后,我想到了这个:
#include <iostream>
#include <fstream>
class ScopedRedirect
{
public:
ScopedRedirect(std::ostream & inOriginal, std::ostream & inRedirect) :
mOriginal(inOriginal),
mRedirect(inRedirect)
{
mOriginal.rdbuf(mRedirect.rdbuf(mOriginal.rdbuf()));
}
~ScopedRedirect()
{
mOriginal.rdbuf(mRedirect.rdbuf(mOriginal.rdbuf()));
}
private:
ScopedRedirect(const ScopedRedirect&);
ScopedRedirect& operator=(const ScopedRedirect&);
std::ostream & mOriginal;
std::ostream & mRedirect;
};
int main()
{
std::cout << "Before redirect." << std::endl;
std::ofstream filestream("redirected.txt");
{
ScopedRedirect redirect(std::cout, filestream);
std::cout << "During redirect." << std::endl;
}
std::cout << "After redirect." << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
它似乎工作正常.然而,它的怪异的是,下面一行是在重复这两个构造函数和析构函数:
mOriginal.rdbuf(mRedirect.rdbuf(mOriginal.rdbuf()));
Run Code Online (Sandbox Code Playgroud)
我认为这是正确的,但我想与SO社区进行核实.你能在这段代码中发现任何错误或危险吗?
编辑使不可复制.
根据文档,可以通过两种方式初始化互斥锁:
使用init函数:
pthread_mutex_t theMutex;
pthread_mutex_init(&theMutex, NULL);
Run Code Online (Sandbox Code Playgroud)
使用初始化宏:
pthread_mutex_t result = PTHREAD_MUTEX_INITIALIZER;
Run Code Online (Sandbox Code Playgroud)
关于后者文件说:
在默认互斥锁属性适当的情况下,宏PTHREAD_MUTEX_INITIALIZER可用于初始化静态分配的互斥锁.通过调用pthread_mutex_init()并将参数attr指定为NULL,该效果应等效于动态初始化,但不执行错误检查.
这是否意味着它只能用于静态变量而不能用于局部变量?
我想使用以下"工厂功能":
static pthread_mutex_t GetFastNativeMutex()
{
static pthread_mutex_t result = PTHREAD_MUTEX_INITIALIZER;
return result;
}
Run Code Online (Sandbox Code Playgroud)
因为它允许我在C++初始化程序列表中初始化互斥锁,如下所示:
MyClass() : myMutex(GetFastNativeMutex()) {}
Run Code Online (Sandbox Code Playgroud)
这有效吗?(顺便说一句,实际上它很有效.Valgrind也不会抱怨.)
如果我正确理解文档,那么这应该没问题:
#include <pthread.h>
static pthread_mutex_t m0 = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t m1 = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t m2 = PTHREAD_MUTEX_INITIALIZER;
Run Code Online (Sandbox Code Playgroud)
但是,在查看预处理器输出(使用gcc -E main.cpp)时,我看到以下内容:
static pthread_mutex_t m0 = {0x32AAABA7, {0}};
static pthread_mutex_t m1 = {0x32AAABA7, {0}};
static pthread_mutex_t m2 = {0x32AAABA7, {0}};
Run Code Online (Sandbox Code Playgroud)
事实证明,创建了三倍相同的互斥锁.我在这做错了什么?
async下面的调用是阻塞的,因为返回的未来的析构函数是阻塞的:
void foo() {}
void foo_async() {
std::async(std::launch::async, foo);
}
Run Code Online (Sandbox Code Playgroud)
但我不想阻止!
我正在考虑使用以下解决方法:
void foo_async() {
std::thread(foo).detach();
}
Run Code Online (Sandbox Code Playgroud)
这个可以吗?或者你会推荐一个不同的解决方案?
我试用了令人印象深刻的演示应用程序.然而,构建它并将其与我自己的代码集成很难,因为它是一个如此庞大的项目.
有没有人成功地将它用于自己的项目?难以构建并与您自己的C++代码集成吗?
链接:STLab.
对于感兴趣的人:还有一个Google Tech Talk澄清了该项目背后的哲学思想.
我最近学到了一些关于对齐的知识,但我不确定在哪种情况下它会成为一个问题.我怀疑有两种情况:
第一个是使用数组时:
struct Foo {
char data[3]; // size is 3, my arch is 64-bit (8 bytes)
};
Foo array[4]; // total memory is 3 * 4 = 12 bytes.
// will this be padded to 16?
void testArray() {
Foo foo1 = array[0];
Foo foo2 = array[1]; // is foo2 pointing to a non-aligned location?
// should one expect issues here?
}
Run Code Online (Sandbox Code Playgroud)
第二种情况是使用内存池时:
struct Pool {
Pool(std::size_t size = 256) : data(size), used(0), freed(0) { }
template<class T>
T …Run Code Online (Sandbox Code Playgroud) 您好我正在尝试与boost链接以使用线程库,但似乎无法将其构建.
我用HomeBrew(mac包安装程序)安装了boost,它在/usr/local/Cellar/boost/1.50.0目录中.
我的主文件现在很简单......
#include <iostream>
#include <boost/thread.hpp>
Run Code Online (Sandbox Code Playgroud)
我的make文件是这样的:
CC = g++
BASE_FLAGS = -m32 -wAll
# INCLUDE BASE DIRECTORY AND BOOST DIRECTORY FOR HEADERS
LDFLAGS = -I/usr/local/Cellar/boost/1.50.0/include -I/opt/local/include
# INCLUDE BASE DIRECTORY AND BOOST DIRECTORY FOR LIB FILES
LLIBFLAGS = -L/usr/local/Cellar/boost/1.50.0/
# SPECIFIY LINK OPTIONS
LINKFLAGS = -l boost_thread-mt -lboost_system
# FINAL FLAGS -- TO BE USED THROUGHOUT
FLAGS = $(BASE_FLAGS) $(LLIBFLAGS) $(LDFLAGS) $(LINKFLAGS)
# NOTE FOR BOOST -- YOU ONLY NEED TO INCLUDE THE PATH BECAUSE IT …Run Code Online (Sandbox Code Playgroud) C++标准库是否与编译器绑定,或者可以提供不同的实现?
我很想知道这一点,主要是因为看起来typeid关键字之间的关系std::type_info阻碍了这一点.该typeid关键字依赖于存在的std::type_info,我会认为是在错误的方向上的依赖.我不知道自定义实现应该如何实现该type_info::name()方法.
我的问题是:
std::type_info在他的"C++编程语言"(第三版)一书中, Stroustrup教授在自己的命名空间中定义各个组件,并将它们导入通用命名空间.
例如:
namespace array_api {
struct array {};
void print(const array&) { }
}
namespace list_api {
struct list {};
void print(const list&) { }
}
namespace api {
using array_api::array;
using list_api::list;
}
Run Code Online (Sandbox Code Playgroud)
我看起来很有趣,但我从未见过这种方法在实践中使用过.
为什么这种技术几乎从未使用过?
我目前正在学习如何在C++中进行多线程处理.我的一个学习项目是俄罗斯方块游戏.在这个项目中,我有一个包含所有游戏状态数据的Game类.它有移动块的方法和其他一些东西.用户(将使用箭头键从主线程移动块)访问此对象,同时线程计时器在活动块上实现重力(定期降低它).
起初我以为我可以通过添加互斥成员变量并将其锁定在每个方法调用中来使Game类线程安全.但问题是它只保护单个方法调用,而不是涉及多个方法调用的更改.例如:
// This is not thread-safe.
while (!game.isGameOver())
{
game.dropCurrentBlock();
}
Run Code Online (Sandbox Code Playgroud)
我尝试的一个解决方案是为互斥变量添加一个访问器方法,以便从外部锁定它:
// Extra scope added to limit the lifetime of the scoped_lock.
{
// => deadlock, unless a recursive mutex is used
boost::mutex::scoped_lock lock(game.getMutex());
while (!game.isGameOver())
{
game.dropCurrentBlock();
}
}
Run Code Online (Sandbox Code Playgroud)
但是,除非使用递归互斥锁,否则这将会死锁.现在,看看StackOverflow 上的一些 帖子,似乎有多数人强烈反对使用递归互斥锁.
但是,如果递归互斥锁是非选项,那么这是否意味着创建一个线程安全类(支持协调更改)变得不可能?
唯一有效的解决方案似乎是永远不会在方法调用中锁定互斥锁,而是始终依赖用户从外部进行锁定.
但是,如果是这种情况,那么简单地将Game类保持原样不是更好,并创建一个将Game对象与互斥锁配对的包装类?
我尝试了包装器的想法并创建了一个名为ThreadSafeGame(cpp)的类,如下所示:
class ThreadSafeGame
{
public:
ThreadSafeGame(std::auto_ptr<Game> inGame) : mGame(inGame.release) {}
const Game * getGame() const
{ return mGame.get(); }
Game * getGame()
{ return mGame.get(); …Run Code Online (Sandbox Code Playgroud)