小编my_*_*ion的帖子

unique_ptr,pimpl/forward声明和完整定义

我已经在这里这里检查了问题,但仍然无法弄清楚出了什么问题.

这是调用代码:

#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++ language-lawyer c++11

15
推荐指数
2
解决办法
2900
查看次数

c ++ 11成员函数从unique_ptr的向量返回原始指针的向量

我开始使用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,只是我必须忍受的一些限制.

c++ c++11

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

C++对象名与类名相同

我碰巧写了这样的代码:

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)

c++

8
推荐指数
2
解决办法
8894
查看次数

char*不应该隐式转换为std :: string吗?

这是我的代码:

#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)

c++

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

如何在for_each中使用dynamic_cast

我有以下代码:

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*的向量传递给这段代码.

c++ foreach dynamic-cast

7
推荐指数
2
解决办法
721
查看次数

如果没有堆内存,如何释放std :: vector

我有一个这样的类成员变量:

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的析构函数不调用它的元素的析构函数.

你能确认我的电话吗?

c++ memory-management vector

6
推荐指数
3
解决办法
3486
查看次数

无法在Makefile中调用bash函数

我的印象是我可以在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”。

makefile gnu-make

6
推荐指数
3
解决办法
3612
查看次数

有什么技巧可以使复制构造函数与类属性保持同步吗?

我相信这是一个常见问题,但有些谷歌搜索不会返回匹配项,因此请在这里询问。

所以我有以下课程:

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,但我忘记更新复制构造函数。

需要进行痛苦的调试才能找到不同步的位置。

有没有办法避免这样的问题,最好是在构建时?

是的,我可以编写单元测试来覆盖该复制构造函数,但是当我忘记更新复制构造函数时,很可能我也忘记了该单元测试。

c++

6
推荐指数
1
解决办法
928
查看次数

为什么不使用静态变量作为智能指针的引用计数

当我查看"增强版"智能指针 - 增强是添加引用计数 - 我看到他们使用一些"复杂"技术进行引用计数,例如一个完全独立的类或指向整数的指针.

这是一个例子:

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)

我必须错过一些东西,但经过一番搜索后,我找不到任何答案.请说清楚.

c++ smart-pointers

5
推荐指数
2
解决办法
1704
查看次数

Range元素不能用于解析器规则?

我有以下语法:

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上.

antlr

5
推荐指数
1
解决办法
1103
查看次数