我编写了一个静态工厂方法,它返回从另一个数据对象填充的新Foobar对象.我最近一直沉迷于所有权语义,我想知道我是否通过这种工厂方法返回一个正确的信息unique_ptr.
class Foobar {
public:
static unique_ptr<Foobar> factory(DataObject data);
}
Run Code Online (Sandbox Code Playgroud)
我的目的是告诉客户端代码他们拥有指针.没有智能指针,我只会回来Foobar*.但是,我想强制删除这个内存以避免潜在的错误,所以这unique_ptr似乎是一个合适的解决方案.如果客户端想要延长指针的生命周期,他们只需在调用.release()后调用unique_ptr.
Foobar* myFoo = Foobar::factory(data).release();
Run Code Online (Sandbox Code Playgroud)
我的问题分为两部分:
unique_ptr而不是原始指针这是一个"坏习惯" 吗?我对C++比较陌生,在工作中处理一个相当大的C++项目.我注意到一些函数将双指针作为函数将在堆上实例化的对象的参数.例:
int someFunc(MyClass** retObj) {
*retObj = new MyClass();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我只是不确定为什么在这个项目中总是使用双指针,而不仅仅是一个指针?这主要是一个语义提示,它是一个输出/返回参数,还是有一个我没有看到的技术原因?
我不想在这里问一个有意的主观问题,但我没有其他人直接问这个问题......
我正在尝试通过在我编写的新代码中采用更现代的C++概念,在我的团队中"以身作则".我的同事有点害羞的模板,并且抱怨不得不键入unique_ptr<Foobar>或者shared_ptr<Foobar>只是Foobar*在使用我最近创建的一些类时(工厂方法返回unique_ptrs并且我使用这些对象存储这些对象的列表shared_ptr).
他们扭曲了我的胳膊,并说服我将这些类型变成更容易打字的东西,例如FoobarUniquePtr.
但是现在我对这些typedef的const-correctness一团糟.我必须为每个const和非const类型定义额外的typedef,并且const const_FoobarUniquePtr似乎没有正确表达const语义.
所以,就我的问题而言,auto当他们抱怨不得不输入模板化的智能指针时,停止使用这些typedef是否有意义而不是推向我的队友?我也对其他选择持开放态度.
我在Chrome中使用css3的flexbox(无需担心跨浏览器).我很难说服它以我喜欢的方式布置我的内容.这是我的目标草图:

这是我尝试的jsFiddle:http://jsfiddle.net/Yht4V/2/这看起来效果很好,除了每个.group都会扩展它的高度而不是创建多个列.
我在这里普遍使用flexbox.在body垂直放置,用#contentDIV服用页面的剩余高度.每个.group都是水平布局的.最后,每个.item都是在.group垂直方向上进行包装.
不幸的是,每个都.group通过扩展#content高度而最终成为单个列,从而导致垂直滚动条(不需要的).如果我将每个的高度设置.group为固定的像素大小,则项目会分成多个列,但这会破坏弹性框的流动性.这是固定高度的样子:http://jsfiddle.net/Yht4V/3/
那么,如何#content在不设置固定高度的情况下使用flexbox管理所有内容,我怎样才能使div不垂直扩展?我期待flexbox触发更多列而不是扩展其父级的高度并导致滚动条.
我想有一个unique_ptr的向量作为我正在制作的类的成员.
class Foo {
[...]
private:
vector<unique_ptr<Bar>> barList;
}
Run Code Online (Sandbox Code Playgroud)
但后来我开始从VS2010编译器获取神秘的错误消息:
error C2248: 'std::unique_ptr<_Ty>::operator =' : cannot access private member declared in class 'std::unique_ptr<_Ty>'
Run Code Online (Sandbox Code Playgroud)
除了下面的一些错误行,这些错误行将深入到微软的实施std::_Copy_impl<>......
我将成员声明更改为
vector<unique_ptr<Bar>>* barList;
Run Code Online (Sandbox Code Playgroud)
它编译.但我不禁想知道为什么我不能按照我原来想要的方式去做?为了笑容,我尝试了这个,它工作正常:
vector<Bar> barList;
Run Code Online (Sandbox Code Playgroud)
但现在我失去了方便unique_ptr.我想要我的蛋糕,我也想吃它!
(使用Visual Studio 2010)我正在尝试在我的项目中创建现有类的shared_ptr(类是在std :: shared_ptr存在之前写的十年).该类采用非const指针指向另一个对象,它的空参数构造函数是私有的.
class Foobar {
public:
Foobar(Baz* rBaz);
private:
Foobar();
}
Run Code Online (Sandbox Code Playgroud)
当我尝试创建一个shared_ptr时,事情进展不顺利:
Baz* myBaz = new Baz();
std::shared_ptr<Foobar> sharedFoo = std::make_shared<Foobar>(new Foobar(myBaz));
Run Code Online (Sandbox Code Playgroud)
在VS2010上,这给了我
error C2664: 'Foobar::Foobar(const Foobar &)' : cannot convert parameter 1 from 'Foobar *' to 'const Foobar &'
3> Reason: cannot convert from 'Foobar *' to 'const Foobar'
Run Code Online (Sandbox Code Playgroud)
由于某种原因,它似乎是调用复制构造函数Foobar而不是构造函数Baz*.
我也不确定这个cannot convert from 'Foobar *' to 'const Foobar'部分.我最好的解释是我的模板类型shared_ptr<Foobar>是错误的.我做了,shared_ptr<Foobar*>但这似乎是错的,我见过的所有例子都没有使该类型成为原始指针.
似乎shared_ptr<Foobar*>正确地编译所有内容,但是Foobar当所有内容shared_ptr都超出范围时,是否会阻止对象被正确删除?
编辑: …
我非常喜欢C#中属性的概念,作为一个小小的项目,我一直在修改用C++实现它们的想法.我遇到了这个示例/sf/answers/414721611/这看起来相当不错,但我忍不住认为lambdas和非静态数据成员初始化可能会使用一些非常好的语法有这个想法.这是我的实现:
#include <iostream>
#include <functional>
using namespace std;
template< typename T >
class property {
public:
property(function<const T&(void)> getter, function<void(const T&)> setter)
: getter_(getter),
setter_(setter)
{};
operator const T&() {
return getter_();
};
property<T>& operator=(const T& value) {
setter_(value);
}
private:
function<const T&(void)> getter_;
function<void(const T&)> setter_;
};
class Foobar {
public:
property<int> num {
[&]() { return num_; },
[&](const int& value) { num_ = value; }
};
private:
int num_;
};
int main() {
// This …Run Code Online (Sandbox Code Playgroud) 我在Visual Studio 2010中设置了一个项目,以针对现有的MFC DLL编写单元测试.我正在使用单头单元测试框架,并链接到单元测试项目中的MFC DLL的lib包装器.我正在尝试构建一个接受std::wstring它的构造函数的类.这是我的测试的样子:
TEST_CASE("MyProject/MyTest", "Do the test.")
{
MockDbService mockDbService;
Foobar foo(L"{F00DFACE-FEED-DEAD-BEEF-C0FFEEDECADE}", mockDbService);
foo.loadObject();
REQUIRE(mockDbService.getMethodInvokeCount("query()") >= 1);
}
Run Code Online (Sandbox Code Playgroud)
Foobar从测试中的MFC DLL导出的类在哪里.但是,测试框架会报告意外的异常.std::wstring在将字符串复制到构造函数时,我将其跟踪到了复制构造Foobar函数.MSVC调试器将源字符串报告为<Bad Ptr>.
我创建了一个虚拟构造函数,Foobar::Foobar(long num, IDbService& db)所有的值(包括IDbService&)都很好.
MFC DLL和我的单元测试EXE都共享一个属性表,它应该保持编译器标志等效.我正在调试模式下构建并运行测试.任何想法为什么std::wstring不能跨DLL复制?
我正在尝试设置Qt Win Migration框架以在现有的基于MFC的应用程序中使用Qt.我想将框架用作库,因此我运行qmake该qtwinmigrate/buildlib/buildlib.pro文件来创建Visual Studio vcxproj项目文件.我将框架构建为dll/lib,并将标头放在一个公共的include目录中.在我的MFC项目中,我添加了Qt迁移框架的lib作为依赖项,在适当的地方包含了标头,并添加了测试框架的代码.一切都编译好,但后来我得到一个链接器错误:
错误LNK2001:未解析的外部符号"public:static struct QMetaObject const QWinWidget :: staticMetaObject"(?staticMetaObject @ QWinWidget @@ 2UQMetaObject @@ B)
我有一个Foobar类的sayHello()方法,输出"嗯,你好!".如果我写下面的代码
vector<unique_ptr<Foobar>> fooList;
fooList.emplace_back(new Foobar());
unique_ptr<Foobar> myFoo = move(fooList[0]);
unique_ptr<Foobar> myFoo2 = move(fooList[0]);
myFoo->sayHello();
myFoo2->sayHello();
cout << "vector size: " << fooList.size() << endl;
Run Code Online (Sandbox Code Playgroud)
输出是:
Well hello there!
Well hello there!
vector size: 1
Run Code Online (Sandbox Code Playgroud)
我很困惑为什么这样做.fooList[0]我做第一步时不应该变为空吗?为什么myFoo2工作?
这是Foobar看起来像:
class Foobar
{
public:
Foobar(void) {};
virtual ~Foobar(void) {};
void sayHello() const {
cout << "Well hello there!" << endl;
};
};
Run Code Online (Sandbox Code Playgroud) 我正在尝试git tf clone使用TFVC的Visual Studio Online上的项目,我正在运行以下命令:
git tf clone https://{user-url}.visualstudio.com/DefaultCollection {project_path}
Run Code Online (Sandbox Code Playgroud)
然后它会要求输入用户名和密码,但是当我使用Visual Studio Online的登录凭据时,它将无法登录.
如何从git-tf命令行登录Visual Studio Online?
我想让函数返回特定节点的地址.但是编译器没有检测到我创建的节点数据类型结构.
struct node
{
int data;
node *link;
};
node *header,*current;
node traverse(int pos);
node *Linkedlist::traverse(int pos)
{
int location = 0;
current->link = header->link;
node *address = new node;
address->data = NULL;
address->link = NULL;
while(current->link != NULL)
{
if(location == pos)
{
cout <<current->link->data <<" "<< endl;
address->link=current->link;
}
location ++;
current->link = current->link->link;
}
return address->link;
}
Run Code Online (Sandbox Code Playgroud) 我有些惊讶地发现,std::shared_ptr当它的指向对象以某种方式被删除时,它不提供保护(例如,抛出异常).我想这是出于性能原因; 假设shared_ptr正在完成其工作的对象shared_ptr应该从未删除过的点,因此浪费周期不断检查是愚蠢的.
我知道我可以明确检查a shared_ptr是否有效,但是如果shared_ptr"做它的工作"来维持对象的生命周期,那么每次触摸时都要明确检查是否有点过分shared_ptr.
所以我的问题是,鉴于此,我应该多么谨慎?关于是否,经常或何时应该检查shared_ptr?是否有"经验法则" ?
到目前为止,我最好的结论是模仿Java:每当你提交一个你没有创建的Java对象的引用时,你应该检查它null.这是一个很好的政策shared_ptr吗?
c++ ×10
c++11 ×4
shared-ptr ×2
unique-ptr ×2
css ×1
css3 ×1
dll ×1
flexbox ×1
gcc ×1
git-tf ×1
lambda ×1
make-shared ×1
mingw ×1
qt ×1
stl ×1
vector ×1
visual-c++ ×1
webkit ×1