Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/131.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 限制轻类实例化_C++_Oop_Opengl_Static_Limit - Fatal编程技术网

C++ 限制轻类实例化

C++ 限制轻类实例化,c++,oop,opengl,static,limit,C++,Oop,Opengl,Static,Limit,我有一个“Light”类,它的功能是开箱即用的,但我知道OpenGL在任何时候都只允许有限数量的灯光处于活动状态。根据glGetIntegerfv(GL_MAX_LIGHTS,…)MAX LIGHTS是8,所以我应该只允许Light类在编译时或运行时实例化8次 我尝试了一种解决问题的方法: int Light::sCounter = 0; Light::Light() : // initialiser-list { sCounter++; if (sCounter >

我有一个“Light”类,它的功能是开箱即用的,但我知道OpenGL在任何时候都只允许有限数量的灯光处于活动状态。根据
glGetIntegerfv(GL_MAX_LIGHTS,…)
MAX LIGHTS是8,所以我应该只允许Light类在编译时或运行时实例化8次

我尝试了一种解决问题的方法:

int Light::sCounter = 0;

Light::Light() : // initialiser-list
{
    sCounter++;

    if (sCounter > getMaxLightCount())
        // do something, but what?
}
其中,sconter是一个
静态int
getMaxLightCount()
调用前面提到的OpenGL函数。如果计数器高于最大灯数,则应发生某些情况;但我不知道该如何回应。我不能在构造函数中返回NULL或其他内容,但我一直在寻找异常来解决这个问题;虽然我通常不喜欢例外,因为它使情况变得过于复杂。我还研究了如何实现一个Manager类,但这会使事情变得不直观,因为它实际上意味着用户不会调用Light类,而是调用其中的Manager


在限制Light类的实例化数量方面,我有哪些选择,以及哪种解决方案能够有效地直观地重用?

我认为让创建Light的任何类都保持计数,而不是试图在
Light
类本身中处理计数,这将更有意义


如果你有很多灯光拥有者,最好建立一个可以获得灯光的水池,如果需要,您甚至可以创建一种机制,通过该机制,一个客户机可以请求不同的客户机放弃灯光。

如果它不是太严格,您可以防止实例化
灯光
类,除非使用工厂。下面的示例需要C++11,但可以在没有C++11的情况下工作(尽管需要更多的工作,使用boost等)

即使下面的例子还不够,也可能会给你一些想法

示例代码
我将从外部管理计数,因此,管理器类将执行您所说的计数?这是一个很好的情况,池设置为可配置的限制将非常有用。如果有一位经理能够跟踪该池的情况,这也将是有益的。当我们可以从类外部调用destroyFoo函数时,为什么要传递一个指向它的指针?@Poriferous我相信这是
std::unique_ptr
中自定义删除程序所需的函数签名(请参阅“类型要求”部分)。但是你是对的,这个函数是公共的没有意义,我把它更新为私有的;否则,使用light3.get_deleter()?@Poriferous就相当于使用light3.get_deleter()?@Poriferous这只是一个示例,让您了解如何处理它。如果您希望对对象的生命周期进行更多控制,那么可能需要添加一个公共函数,该函数采用
Light::Ptr
。我将更新示例以显示这一点。
#include <iostream>
#include <functional>
#include <memory>

class Light
{
public:
    using Ptr = std::unique_ptr<Light, std::function<void (Light*)>>;

    static void destroyLight(Ptr light)
    {
        // Do nothing, 'light' will be deleted when it falls out of scope
    }

    static Ptr createLight()
    {
        if (sInstanceCount < MAX_INSTANCE_COUNT)
        {
            ++sInstanceCount;
            return Ptr(new Light(), &Light::destroyLightImpl );
        }
        else
        {
            return Ptr();
        }
    }

private:
    Light() {} // Prevent others from creating instances
    ~Light() {} // Prevent others from deleting instances

    static void destroyLightImpl(Light* light)
    {
        delete light;
        --sInstanceCount;
    }

    static const int MAX_INSTANCE_COUNT = 3;
    static int sInstanceCount;
};

int Light::sInstanceCount = 0;

int main()
{
    Light::Ptr light1 = Light::createLight();
    Light::Ptr light2 = Light::createLight();
    std::cout << light1.get() << "\n";
    std::cout << light2.get() << "\n";

    Light::Ptr light3 = Light::createLight();
    Light::Ptr light4 = Light::createLight();
    std::cout << light3.get() << "\n";
    std::cout << light4.get() << "\n";

    Light::destroyLight(std::move(light3));
    Light::Ptr light5 = Light::createLight();
    std::cout << light5.get() << "\n";

    return 0;
}
005872C0
005872F0
00587320
00000000
00587320