2016-07-25 89 views
1

当我尝试编译下面的代码:C++编译SFML错误SF ::不可复制::不可复制(常量SF ::不可复制&)是私人

SFMLSet.cpp:

#include "SFMLSet.h" 

SFMLSet::SFMLSet(string texturePath) 
{ 
    if(!texture.loadFromFile(texturePath)) { 
     exit(1); 
    } 
    new (&app) sf::RenderWindow(sf::VideoMode(texture.getSize().x, texture.getSize().y), texturePath, sf::Style::None); 
    new (&sprite) sf::Sprite(texture); 
} 

SFMLSet.h :

#ifndef SFMLSET_H 
#define SFMLSET_H 
#include <SFML/Graphics.hpp> 
#include <string> 
#include <cmath> 
using namespace std; 

class SFMLSet { 
    public: 
     sf::RenderWindow app; 
     sf::Texture texture; 
     sf::Sprite sprite; 

     sf::Vector2i grabbedOffset; 
     bool grabbedWindow = false; 

     SFMLSet (string texturePath); 

     sf::Event event; 
}; 


#endif // SFMLSET_H 

main.cpp中:

#include <windows.h> 
#include <vector> 
#include <iostream> 

#include "SFMLSet.h" 


int main() 
{ 
    bool isRunning=true; 
    vector<SFMLSet> IMGS; 
    IMGS.push_back (SFMLSet ("cb.bmp")); 

    while (isRunning) 
    { 
     for (int i=0;i<IMGS.size();i++) { 
     while (IMGS[i].app.pollEvent(IMGS[i].event)) 
     { 
      if (IMGS[i].event.type == sf::Event::Closed) { 
       IMGS[i].app.close(); 
       isRunning=false; 
      } 
      if (IMGS[i].event.type == sf::Event::KeyPressed && IMGS[i].event.key.code == sf::Keyboard::Escape) 
         { 
           IMGS[i].app.close(); 
           isRunning=false; 
         } 
         else if (IMGS[i].event.type == sf::Event::MouseButtonPressed) 
         { 
           if (IMGS[i].event.mouseButton.button == sf::Mouse::Left) 
           { 
             IMGS[i].grabbedOffset = IMGS[i].app.getPosition() - sf::Mouse::getPosition(); 
             IMGS[i].grabbedWindow = true; 
           } 
         } 
         else if (IMGS[i].event.type == sf::Event::MouseButtonReleased) 
         { 
           if (IMGS[i].event.mouseButton.button == sf::Mouse::Left) 
             IMGS[i].grabbedWindow = false; 
         } 
         else if (IMGS[i].event.type == sf::Event::MouseMoved) 
         { 
           if (IMGS[i].grabbedWindow&&(IMGS[i].grabbedOffset.x<-10&&IMGS[i].grabbedOffset.y<-10)&&(IMGS[i].grabbedOffset.x>-(IMGS[i].texture.getSize().x)+10&&IMGS[i].grabbedOffset.y>-(IMGS[i].texture.getSize().y)+10)) 
             IMGS[i].app.setPosition(sf::Mouse::getPosition() + IMGS[i].grabbedOffset); 
         } 
     } 

     IMGS[i].app.clear(); 

     IMGS[i].app.draw(IMGS[i].sprite); 

     IMGS[i].app.display(); 
     } 
    } 

    return EXIT_SUCCESS; 
} 

我收到一些错误:

SFML-2.3.2\include/SFML/System/NonCopyable.hpp:67:5: error: 'sf::NonCopyable::NonCopyable(const sf::NonCopyable&)' is private

SFML-2.3.2\include/SFML/Window/Window.hpp:57:23: error: within this context

SFML-2.3.2\include/SFML/System/NonCopyable.hpp:67:5: error: 'sf::NonCopyable::NonCopyable(const sf::NonCopyable&)' is private

SFML-2.3.2\include/SFML/Graphics/RenderTarget.hpp:51:25: error: within this context

SFML-2.3.2\include/SFML/System/NonCopyable.hpp:79:18: error: 'sf::NonCopyable& sf::NonCopyable::operator=(const sf::NonCopyable&)' is private

SFML-2.3.2\include/SFML/Window/Window.hpp:57:23: error: within this context

SFML-2.3.2\include/SFML/System/NonCopyable.hpp:79:18: error: 'sf::NonCopyable& sf::NonCopyable::operator=(const sf::NonCopyable&)' is private

SFML-2.3.2\include/SFML/Graphics/RenderTarget.hpp:51:25: error: within this context

如何解决这个问题?

+1

我不想听起来粗鲁,但从正确学习C++的基础开始。例如,'new(&app)sf :: RenderWindow(...'是**不是**你应该在这里做什么。 – Hiura

回答

4

您应该阅读SFML tutorials,并编写像他们的例子一样的程序。

这里的具体问题是sf::RenderWindow的拷贝构造函数是私有的 - 通常复制一个窗口是没有意义的。

不幸的是,您在std::vector中使用了SFMLSet。矢量必须动态增大其大小,为了实现这一点,他们分配一个新的更大的缓冲区,并将其现有内容复制到新位置 - 调用SFMLSet的复制构造函数,该构造函数依次尝试调用sf::RenderWindow s。

解决此问题的最佳方法是从IMGS中删除sf::RenderWindow,并将其作为局部变量保存在main中,如同在教程中一样。你可能不打算为每个图像打开一个新窗口,对吧?

+0

如果你使用移动类型,你不能使用'std :: vector' 'emplace_back'而不是'push_back'?但我同意使用'sf :: RenderWindow'有什么问题:'app'应该是一个指向窗口的智能指针 – KABoissonneault

+0

sf :: RenderWindow不可移动 - 它声明了一个私有拷贝构造函数,但是没有移动构造函数,C++ 11支持在他们的路线图上,但还没有实现。 – Dutow

+0

然后它将被动态分配,我猜 – KABoissonneault

2

该错误消息告诉您,您正试图在某处复制sf::NonCopyable的实例。编译器说你正试图调用该类的复制构造函数,但该复制构造函数是私人定义的,因此无法访问。

要修复它,您需要计算出导致sc::NonCopyable实例被复制的原因,并更改该代码,使其没有副本(可能使用指针)。