小编Whe*_*050的帖子

在std :: shared_ptr中使用自定义删除器

我正在尝试研究如何将std :: shared_ptr与自定义删除器一起使用.具体来说,我将它与SDL_Surface一起用作:

std::shared_ptr<SDL_Surface>(SDL_LoadBMP(....),SDL_FreeSurface);
Run Code Online (Sandbox Code Playgroud)

编译并运行良好.但是,我想尝试自己的删除器,但无法解决如何操作.SDL_FreeSurface的文档可在此处找到:

http://sdl.beuc.net/sdl.wiki/SDL_FreeSurface

我在其中发现SDL_FreeSurface被声明为:

void SDL_FreeSurface(SDL_Surface* surface);
Run Code Online (Sandbox Code Playgroud)

作为测试,并通过该信息,我尝试了以下功能:

void DeleteSurface(SDL_Surface* surface)
{
    std::cout << "Deleting surface\n";
    SDL_FreeSurface(surface);
}
Run Code Online (Sandbox Code Playgroud)

但是,使用g ++编译会出现以下错误:

error: no matching function for call to 'std::shared_ptr<SDL_Surface>::shared_ptr(SDL_Surface*, <unresolved overloaded function type>)'
Run Code Online (Sandbox Code Playgroud)

我已经查看了gcc std :: shared_ptr实现的gnu文档,但是对它没有多大意义.我究竟做错了什么?

编辑:我已经缩小了问题的范围,但是会留下上面的原始问题.我所拥有的是一个Game类,如果我将其删除为基本实现,则类似于:

class Game {
    public:
        /* various functions */
    private:
        void DeleteSurface(SDL_Surface* surface);
        bool CacheImages();
        std::vector<std::shared_ptr<SDL_Surface> > mCachedImages;

        /* various member variables and other functions */
}
Run Code Online (Sandbox Code Playgroud)

与上述执行DeleteSurface一样,执行CacheImages()如下:

bool CacheImages()
{
    mCachedImages.push_back(std::shared_ptr<SDL_Surface>(SDL_LoadBMP(...),DeleteSurface);
    return true;
}
Run Code Online (Sandbox Code Playgroud)

哪个游戏我上面列出的错误.但是,如果我将该DeleteSurface() …

c++ shared-ptr

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

C++ Vector push_back()的详细信息

我正在尝试调试一个程序,这样做已经碰到了我对C++向量push_back()函数的理解.

为了说明我的观点,我写了以下简短程序:

#include <iostream>
#include <vector>
#include <cstdlib>

using std::cout;
using std::endl;
using std::vector;

class Test {
private:
  int mTestMember;
public:
  Test(int val);
  Test(const Test&);

  int GetValue() const;
};

Test::Test(int val)
{
  cout << "Constructor\n";
  mTestMember = val;
}

Test::Test(const Test& test)
{
  cout << "Copy Constructor\n";
  mTestMember = test.mTestMember;
  cout << "mTestMember: " << mTestMember << endl;
}

int main(){

  vector<Test> tests;
  tests.push_back(Test(int(5)));
  cout<< endl;
  tests.push_back(Test(int(6)));
  cout << endl;
  tests.push_back(Test(int(7)));

  return(0);
}
Run Code Online (Sandbox Code Playgroud)

如果我编译并运行,我得到以下输出:

Constructor
Copy Constructor
mTestMember: 5

Constructor …
Run Code Online (Sandbox Code Playgroud)

c++ vector

7
推荐指数
1
解决办法
2529
查看次数

使用自定义析构函数时出现"未定义的引用"错误

我正在尝试编写一个需要释放一些内存的类,所以我已经定义了一个自定义析构函数.这被编译为共享库.但是,当我尝试编译一个基本程序来使用该库时,我找不到定义时通常的"未定义引用"错误.如果我删除析构函数,则不会发生这种情况.

这是一个精简的例子:

头文件:

#ifndef _SKYMAP_H_
#define _SKYMAP_H_

#include <vector>
#include "TCanvas.h"

class BL_Skymap {
 public:
   BL_Skymap();
   ~BL_Skymap();

 protected:
   TCanvas mCanvas;
};

#endif //_BENSLIBRARY_SKYMAP_H_
Run Code Online (Sandbox Code Playgroud)

源文件:

\#include "BL_Skymap.h"

BL_Skymap::BL_Skymap()
{
}

BL_Skymap::~BL_Skymap()
{
}
Run Code Online (Sandbox Code Playgroud)

现在我正在使用的程序就是这样:

\#include "BL_Skymap.h"

int main()
{
  BL_Skymap map;
  return(0);
}
Run Code Online (Sandbox Code Playgroud)

请注意,我正在使用ROOT分析包(即TCanvas对象).当我编译上面的小程序时,我得到以下错误(Skymap类被编译成libMyLibrary.so):

g++ test.cpp -o test -lMyLibrary `root-config --cflags --glibs`
/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../lib/libMyLibrary.so: undefined reference to 'TCanvas::~TCanvas()'
/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../lib/libMyLibrary.so: undefined reference to 'TCanvas::TCanvas(bool)'
Run Code Online (Sandbox Code Playgroud)

请注意,root包提供了一个实用程序来生成所需的编译器标志,这是root-config --cflags --glibs上面的目的.我在这里错过了什么?

更新:我编写了一个Makefile来执行我的库的编译,它执行以下操作:

g++ -Wall -Wextra -ansi -pedantic --std=c++11 -Isrc -Ihdr -MM -MT 'obj/BL_Skymap.o' src/BL_Skymap.cpp -MF …
Run Code Online (Sandbox Code Playgroud)

c++ root-framework

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

Doxygen使用默认参数重复c ++函数

我正在使用Doxygen来记录我的一些代码.我有一个使用默认参数的函数,它在标题中指定,即:

unsigned int CountColumns(const std::string&,const std::string& delim="");
Run Code Online (Sandbox Code Playgroud)

以及源文件中的相应实现如下:

unsigned int CountColumns(const string& input,const string& delim)
{
   ...
}
Run Code Online (Sandbox Code Playgroud)

当我使用Doxygen生成我的文档时,CountColumns有两个条目 - 一个包含默认值,另一个没有:

unsigned int    CountColumns (const string &input, const string &delim)
unsigned int    CountColumns (const std::string &, const std::string &delim="")
Run Code Online (Sandbox Code Playgroud)

如何避免这种情况?我不希望多个函数定义混乱我的文档.

编辑:正如我在下面的回答中提到的,问题似乎是由于头文件在参数中使用'std :: string',而源文件包含'using std :: string'声明然后在参数中使用'string'.如果我改变函数定义以在源文件中使用'std :: string',Doxygen会将其识别为与标头中声明的函数相同的函数.

c++ doxygen

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

在析构函数中删除指针时崩溃

我遇到了对C++指针缺乏深刻理解的问题.我写了一个名为Skymap的类,它有以下定义:

class Skymap {
 public:
  Skymap();
  ~Skymap();
  void DrawAitoffSkymap();
 private:
  TCanvas mCanvas;

  TBox* mSkymapBorderBox;
};
Run Code Online (Sandbox Code Playgroud)

功能定义为:

#include "Skymap.h"

Skymap::Skymap()
{
  mCanvas.SetCanvasSize(1200,800);
  mMarkerType=1;
}

Skymap::~Skymap()
{
  delete mSkymapBorderBox;
}

void Skymap::DrawAitoffSkymap()
{
  TBox* mSkymapBorderBox=new TBox(-200,-100,200,100);
  //Use the mSkymapBorderBox pointer for a while
}
Run Code Online (Sandbox Code Playgroud)

(我正在使用ROOT绘图包,但我认为这只是一个普通的C++问题).

现在,以下程序在到达skymap2的析构函数时会崩溃:

int main(){
  Skymap skymap1;
  Skymap skymap2;
  skymap1.DrawAitoffSkymap();
  skymap2.DrawAitoffSkymap();
  return(0);
}
Run Code Online (Sandbox Code Playgroud)

但是,以下内容不会崩溃:

int main(){
  Skymap skymap1;
  skymap1.DrawAitoffSkymap();
  return(0);
}
Run Code Online (Sandbox Code Playgroud)

此外,如果我在构造函数中将指针mSkymapBorderBox初始化为NULL,则在执行第一个程序(使用2个Skymap对象)后,我不会再遇到崩溃.

任何人都可以解释一下其根本原因是什么?它似乎是第二个Skymap对象中指针的问题,但我看不出它是什么.

c++ pointers destructor

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

找不到C++默认构造函数

我在Visual C++ 2010 Express中遇到了一些代码问题.我正在尝试创建一个具有构造函数的类,该构造函数接受具有默认值的参数.这是一个简短的程序,显示了我想要实现的目标:

//Class declaration
class Class {
private:
    int mValue;
public:
    Class(int);
    int GetValue();
};

Class::Class(int val=1) : mValue(val)
{
}

int Class::GetValue()
{
    return mValue;
}

int main()
{
    Class test;
    cout << test.GetValue() << endl;
}
Run Code Online (Sandbox Code Playgroud)

现在这似乎工作正常.如果我更换Class testClass test(10),比方说,mValue正确初始化.

但是,在第二个程序中,我试图做同样的事情.我有一个这样定义的类:

namespace mobs {
    Class Monster {
    private:
        mHitPoints;
    public:
        Monster(int);
        int GetHitPoints() const;
    };
}
Run Code Online (Sandbox Code Playgroud)

与这样的功能的实现:

namespace mobs {

    Monster::Monster(int hp=10) : mHitPoints(hp)
    {
    }

    int Monster::GetHitPoints() const
    {
        return …
Run Code Online (Sandbox Code Playgroud)

c++ constructor

2
推荐指数
1
解决办法
1091
查看次数

***glibc检测到***free():指针无效:

我完全被上述glibc错误的原因所困扰.我必须遗漏一些明显的东西,但每次出现以下程序(由4个文件组成)时都会出现:

TankSim.h:

#ifndef TANKSIM_WDECAY_TANKSIM_H_
#define TANKSIM_WDECAY_TANKSIM_H_

#include <cstdlib>
#include <iostream>

#include "Parser.h"

int main();

#endif
Run Code Online (Sandbox Code Playgroud)

TankSim.cpp:

#include "TankSim.h"

using std::cout;
using std::endl;

int main()
{
     const Settings gGlobals = ParseConfig();

     return(0);
}
Run Code Online (Sandbox Code Playgroud)

Parser.h:

#ifndef TANKSIM_WDECAY_PARSER_H_
#define TANKSIM_WDECAY_PARSER_H_

#include <cstdlib>
#include <vector>
#include <fstream>
#include <sstream>
#include <iostream>

struct Settings {
  double speedlight;
  double refractiveindex;
  double absorptionchance;
  double pmtradius;
  double photspermetre;
  double tankradius;
  double tankheight;
  long unsigned int randomseed;
  double scatterangle;
  std::vector<double> entrypoint;
  std::vector<double> entrydrn;
};

Settings ParseConfig();

#endif
Run Code Online (Sandbox Code Playgroud)

Parser.cpp:

#include …
Run Code Online (Sandbox Code Playgroud)

c++ glibc

2
推荐指数
1
解决办法
8397
查看次数

没有尖括号可以调用模板化功能吗?

关于在C++ 11中调用模板化函数需要什么,我有点困惑,其中为模板参数提供了默认值.

例如,假设我有以下模板化函数

template <class T = double> void foo()
{
  /* Do something */
}
Run Code Online (Sandbox Code Playgroud)

我想在我的代码中的某个地方调用它.所有这些有效的电话都是?

foo(); //Is this OK?
foo<>();
foo<int>();
Run Code Online (Sandbox Code Playgroud)

它与GCC 4.7.2编译得很好,但我不确定它是否是严格正确的C++.我想我的不确定性可能来自<>使用默认模板创建模板化类的实例时使用空尖括号的要求,如下所述:

模板默认参数

但我认为在我的情况下,功能括号()是关键区别?

templates c++11

2
推荐指数
1
解决办法
876
查看次数

为什么变量会自动通过引用传递?

我试图在ROOT绘图包中调用一个接受三个变量的函数.我的代码中的相关部分是:

int xwidth=0,ywidth=0;
Bool_t useangle=0;
vIt->GetBoundingBox(xwidth,ywidth,useangle);
Run Code Online (Sandbox Code Playgroud)

其中vIt是GetBoundingBox作为类成员函数的对象的迭代器.(Bool_t只是ROOT使用的typedef).

现在,当我编译时,我从g ++中得到以下错误:

error: no matching function for call to ‘TText::GetBoundingBox(int&, int&, Bool_t&)’
/home/bwhelan/Programs/MODIFIED//External/root/5.30.00/include/root/TText.h:57: note:   candidates are: virtual void TText::GetBoundingBox(UInt_t&, UInt_t&, Bool_t)
Run Code Online (Sandbox Code Playgroud)

我的问题是为什么在这里通过引用传递useangle而不是值?我根本想不出来.

c++

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