Проверьте, создан ли класс в методе - PullRequest
0 голосов
/ 19 июня 2020

У меня есть класс, в котором есть несколько c функций, которые могут быть вызваны, даже если нет экземпляра этого класса. Также есть метод init(), который я использую для установки некоторых переменных. Этот метод не является stati c, поэтому ему нужен экземпляр. Теперь, если это было сделано, я хочу, чтобы методы stati c вели себя иначе. Вроде как:

static foo(){
  if(noInstance()){
    doA();
  }else(){
    doB();
  }
}

Это вообще возможно? Или это плохая идея, и нужно просто заставить пользователя вызывать разные методы, если есть экземпляр? Спасибо

EDIT Звучит странно, но это мой вариант использования:

class A{

public:
    static inline bool hasInstance = false;
    int data;

static int getData(){
    if(hasInstance){
        return data; // Can't do this from a static function
    }else{
        return 0;
    }
}

};

Я знаю, что не могу получить доступ к данным из функции stati c, потому что там не является указателем this. Я кодирую библиотеку, и я хочу, чтобы пользователь мог использовать метод stati c, если ему не нужен экземпляр, но если есть is экземпляр, он должен использовать данные его экземпляр.

Если бы у меня была идея, но я не знаю, хороший ли это стиль:

static int getData(A *ref){
    if(ref != nullptr){
        return data;
    }else{
        return 0;
    }
}

Я был бы рад услышать от кого-то с большим опытом, должен ли я это сделать.

Ответы [ 3 ]

4 голосов
/ 19 июня 2020

Я думаю, вы можете использовать переменную stati c, пусть она будет называться count. Вы инициализируете счетчик с 0, и каждый раз, когда вы создаете экземпляр этого класса, вы увеличиваете счетчик. Если count равен 0, это означает, что вы не создавали ни одного экземпляра, поэтому вы не можете использовать некоторые методы.

1 голос
/ 19 июня 2020

Я кодирую библиотеку и хочу, чтобы пользователь мог использовать метод stati c, если ему не нужен экземпляр, но если он есть, он должен использовать данные его экземпляр.

Как правило, рекомендуются бесплатные функции, а не функции-члены ( gotw ). На самом деле редко есть веские причины сделать функцию stati c функцией-членом. Он должен быть членом, если ему потребуется доступ к частным лицам класса, но, похоже, здесь это не так, и тогда это может быть функция друга.

Давайте посмотрим на ваш подход:

static int getData(A *ref){
    if(ref != nullptr){
        return data;
    }else{
        return 0;
    }
}

Вы, вероятно, хотели написать ref->data;, также я полагаю, вы не просто возвращаете значение члена. Это было бы бесполезно, потому что, если у меня есть экземпляр, я могу получить x.data без необходимости звонить getData. И я полагаю, что 0 - это просто заполнитель для какого-то другого значения, которое у вас есть в реальном коде.

Я сейчас немного субъективен ...

Если бы я был пользователем вашей библиотеке, я хотел бы знать, возвращает ли getData данные одного из созданных мной объектов или чего-то еще. Наличие одной и той же функции, которая выполняет обе функции, сбило бы меня с толку. Я не люблю указатели и боюсь нулевых указателей, поэтому, если вы заставите меня написать

getData(nullptr);

, это не сделает меня счастливым. Я хотел бы иметь две разные функции:

int getData() { return 0; }
int getData(const A& x) { return x.data; }

Если у меня нет экземпляра, я могу вызвать первую, если у меня есть одна, я могу вызвать вторую.

0 голосов
/ 19 июня 2020

Не уверен, какова ваша конечная цель, но я бы рекомендовал пересмотреть ваш дизайн, потому что это поведение static / hasInstance дурно. В любом случае, вот что вам нужно:

using namespace std;

#include <iostream>

class MyClass
{
private:
    static bool hasInstance;
public:
    MyClass()
    {
        hasInstance = true;
    }

    static void foo()
    {
        if (hasInstance) {
            std::cout << "I have an instance\n";
        }
        else {
            std::cout << "No instance\n";
        }
    }
};

bool MyClass::hasInstance = false;

int main () {
    MyClass::foo();
    MyClass a;
    a.foo();
    MyClass::foo();
    return 0;
}

EDIT: не используйте это в реальном коде. Если вам просто любопытно, вы можете делать почти все на C ++, поэтому иногда вы можете передавать объект, он грязный и некрасивый, но только для демонстрации: using namespace std;

#include <iostream>

class MyClass
{
private:
    int someVariable;
public:
    MyClass()
    {
        someVariable = 42;
    }

    static void foo(MyClass *obj = nullptr)
    {
        if (obj) {
            std::cout << obj->someVariable << std::endl;
        }
        else {
            std::cout << "No instance\n";
        }
    }
};

int main () {
    MyClass::foo();
    MyClass a;
    a.foo(&a);
    MyClass::foo(&a);
    return 0;
}
...