我已经在这里和这里检查了问题,但仍然无法弄清楚出了什么问题.
这是调用代码:
#include "lib.h"
using namespace lib;
int
main(const int argc, const char *argv[])
{
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这是lib代码:
#ifndef lib_h
#define lib_h
#include <string>
#include <vector>
#include <memory>
namespace lib
{
class Foo_impl;
class Foo
{
public:
Foo();
~Foo();
private:
Foo(const Foo&);
Foo& operator=(const Foo&);
std::unique_ptr<Foo_impl> m_impl = nullptr;
friend class Foo_impl;
};
} // namespace
#endif
Run Code Online (Sandbox Code Playgroud)
clang ++给了我这个错误:
将'sizeof'无效应用于不完整类型'lib :: Foo_impl'
注意:在成员函数'std :: default_delete :: operator()'的实例化中请求
你可以看到我已经特别声明了Foo析构函数.我还缺少什么?
我开始使用c ++ 11功能,我喜欢使用智能指针只拥有对象.这是我的班级:
class MyClass {
public:
vector<MyObject*> get_objs() const;
private:
vector<unique_ptr<MyObject>> m_objs;
};
Run Code Online (Sandbox Code Playgroud)
语义是MyClass拥有一系列MyObject通过make_unique()创建的.get_objs()返回原始指针的向量,以便各种调用者更新对象.因为那些调用者不拥有对象,所以函数不返回vector<unique_ptr>.
但这意味着我需要get_objs()像这样实现:
vector<MyObjects*> MyClass::get_objs() const
{
vector<MyObjects*> ret;
for (auto obj : my_objs) {
ret.push_back(obj->get());
}
return ret;
}
Run Code Online (Sandbox Code Playgroud)
get_objs()每次有一个开销来构造这个原始指针向量时,我会经常调用我的问题.
我能在这做些什么吗?如果没有c ++ 11技巧来节省开销,我应该首先使用type vector<MyObject*>for m_objs?
UPDATE 1
Run Code Online (Sandbox Code Playgroud)
使用Jonathan Wakely的解决方案operator[]改进了我的解决方案,以便调用者可以直接访问单个对象.
还有其他解决方案吗?我不介意去所有的地方打电话,get_objs(),但想看看是否有更好的解决方案.
另一个注意事项 - 我不能使用BOOST,只是我必须忍受的一些限制.
我碰巧写了这样的代码:
class a
{
public:
a() {}
};
int main()
{
a *a = new a; // line 10
a a; // line 11
return 0;
}
Run Code Online (Sandbox Code Playgroud)
g ++错误输出:
2.c: In function ‘int main()’:
2.c:10:16: error: expected type-specifier before ‘a’
2.c:10:16: error: cannot convert ‘int*’ to ‘a*’ in initialization
2.c:10:16: error: expected ‘,’ or ‘;’ before ‘a’
2.c:11:7: error: expected ‘;’ before ‘a’
Run Code Online (Sandbox Code Playgroud)
我发现,如果我在第10行将"a*a"更改为"a*b",那么g ++很高兴,这是一个很好的代码:
class a
{
public:
a() {}
};
int main()
{
a *b = new a; …Run Code Online (Sandbox Code Playgroud) 这是我的代码:
#include <iostream>
using namespace std;
struct ST {};
bool operator==(const struct ST *s1, const string &s2) {
return true;
}
int main() {
struct ST *st = new ST();
const char *p = "abc";
if (st == p) {
return 0;
}
return 1;
}
Run Code Online (Sandbox Code Playgroud)
我得到编译错误:
prog.cpp:14:12: error: comparison between distinct pointer types ‘ST*’ and ‘const char*’ lacks a cast [-fpermissive]
if (st == p) {
^
Run Code Online (Sandbox Code Playgroud)
我想知道为什么从char*到string的隐式转换在这里不起作用?
更新Anton的答案是有道理的,我更新了代码:
#include <string>
using namespace std;
struct ST {};
bool operator==(const …Run Code Online (Sandbox Code Playgroud) 我有以下代码:
vector<C1*>::iterator itr = vec.begin();
for (; itr != vec.end(); ++itr) {
C2 *c = dynamic_cast<C2*>(*itr);
c->f();
}
Run Code Online (Sandbox Code Playgroud)
我想知道我是否可以使用one-line for_each来替换它.我尝试了以下方法:
for_each(vec.begin(), vec.end(), bind2nd(mem_fun(&C2::f), dynamic_cast<C2*>));
Run Code Online (Sandbox Code Playgroud)
但是我收到编译错误,
expected unqualified-id before 'dynamic_cast'
Run Code Online (Sandbox Code Playgroud)
什么应该是正确的呢?
[编辑]我不能使用c ++ 11.看起来我必须定义一个额外的仿函数,叹息.
关于代码本身的一些问题:C1和C2是2个纯接口; f()仅作为C2的API提供.向量"vec"有一个具有C1和C2接口的对象列表,但它们作为C1*的向量传递给这段代码.
我有一个这样的类成员变量:
vector<vector<int> > m_stacks;
Run Code Online (Sandbox Code Playgroud)
当我填充它时,我喜欢这样:
vector<int> v;
v.push_back(1);
v.push_back(2);
m_stacks.push_back(v);
vector<int> v2;
v2.push_back(1);
v2.push_back(2);
m_stacks.push_back(v2);
Run Code Online (Sandbox Code Playgroud)
现在我想知道我应该在类析构函数中做什么来释放m_stacks.我没有为它分配任何堆内存,所以如果我真的需要做任何事情我就会挣扎.最后我来了 -
vector<vector<int> >::iterator itr = m_stacks.begin();
for ( ; itr != m_stacks.end(); ++itr) {
itr->clear();
}
Run Code Online (Sandbox Code Playgroud)
我认为这是我最需要做的,我不需要打电话m_stacks.clear().原因是vector的析构函数可以自动释放内存.但是我仍然需要上面的代码,原因是vector的析构函数不调用它的元素的析构函数.
你能确认我的电话吗?
我的印象是我可以在GNU makefile中调用bash函数,但是似乎是错误的。这是一个简单的测试,我定义了此功能:
>type lsc
lsc is a function
lsc ()
{
ls --color=auto --color=tty
}
Run Code Online (Sandbox Code Playgroud)
这是我的Makefile:
>cat Makefile
all:
lsc
Run Code Online (Sandbox Code Playgroud)
这是我运行make的过程:
>make
lsc
make: lsc: Command not found
make: *** [all] Error 127
Run Code Online (Sandbox Code Playgroud)
我的印象错了吗?还是有任何环境设置问题?我可以在命令行中运行“ lsc”。
我相信这是一个常见问题,但有些谷歌搜索不会返回匹配项,因此请在这里询问。
所以我有以下课程:
class A {
public:
A(const A &rhs) { m_a = rhs.m_a; }
private:
int m_a;
};
Run Code Online (Sandbox Code Playgroud)
一切都很酷,直到一段时间后,可能是一年后,我添加了一个新属性m_bto class A,但我忘记更新复制构造函数。
需要进行痛苦的调试才能找到不同步的位置。
有没有办法避免这样的问题,最好是在构建时?
是的,我可以编写单元测试来覆盖该复制构造函数,但是当我忘记更新复制构造函数时,很可能我也忘记了该单元测试。
当我查看"增强版"智能指针 - 增强是添加引用计数 - 我看到他们使用一些"复杂"技术进行引用计数,例如一个完全独立的类或指向整数的指针.
这是一个例子:
template<class T>
class SmartPointer{
T* mp_T;
unsigned int * mp_Count;
public:
... all the APIs ...
};
Run Code Online (Sandbox Code Playgroud)
我想知道,收益是多少?由于目标是让所有实例共享值,为什么不将它声明为静态成员变量:
template<class T>
class SmartPointer{
T* mp_T;
static unsigned int m_Count;
public:
... all the APIs ...
};
Run Code Online (Sandbox Code Playgroud)
我必须错过一些东西,但经过一番搜索后,我找不到任何答案.请说清楚.
我有以下语法:
grammar tryout;
tryout : my_cmd
;
my_cmd
: 'start' '0'..'9'+ Name_string
;
Digit
: '0'..'9'
;
Name_string
: ('A'..'Z' | 'a'..'z') ('A'..'Z' | 'a'..'z' | '0'..'9' | '_')*
;
Run Code Online (Sandbox Code Playgroud)
如果我在ANTLRworks中看到图表,'0'..'9'+显示为空元素,因此Java代码编译失败,因为生成的代码具有"if()"语句; 如果我在命令行运行,编译也会失败.
修复是将'0'..'9'+移动到词法分析器规则.
grammar tryout;
tryout : my_cmd
;
my_cmd
: 'start' Digit+ Name_string
;
Digit
: '0'..'9'
;
Name_string
: ('A'..'Z' | 'a'..'z') ('A'..'Z' | 'a'..'z' | '0'..'9' | '_')*
;
Run Code Online (Sandbox Code Playgroud)
但我想知道这是不是一个错误.为什么range元素不能用于解析器规则?这是在ANTLR v3.4上.