我正在尝试研究如何将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++向量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) 我正在尝试编写一个需要释放一些内存的类,所以我已经定义了一个自定义析构函数.这被编译为共享库.但是,当我尝试编译一个基本程序来使用该库时,我找不到定义时通常的"未定义引用"错误.如果我删除析构函数,则不会发生这种情况.
这是一个精简的例子:
头文件:
#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) 我正在使用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++指针缺乏深刻理解的问题.我写了一个名为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对象中指针的问题,但我看不出它是什么.
我在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 test有Class 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) 我完全被上述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++ 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++.我想我的不确定性可能来自<>使用默认模板创建模板化类的实例时使用空尖括号的要求,如下所述:
但我认为在我的情况下,功能括号()是关键区别?
我试图在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++ ×8
c++11 ×1
constructor ×1
destructor ×1
doxygen ×1
glibc ×1
pointers ×1
shared-ptr ×1
templates ×1
vector ×1