Перегрузить сам класс

Предположим, у меня есть класс:

class foo
{
....
//some constructors here set val=34
....
private:
int val;
int & foo::operator,()
{
return val;
}
};

и я хочу иметь возможность использовать его как:

foo bar;
printf("  %d ", bar);   //i need to get value of bar.val
//with just using bar itself with
//using an overloading
//but , overloading does not work
//i need to get 34 without using bar.val
//i need this without any getter
//i need val to be private

Вопрос: возможна ли такая перегрузка? Если да, то как?

Я старался:

int foo::operator int()
{
return val;
}

но он говорит «тип возврата не может быть конкретным для функции преобразования» 🙁

Я старался:

operator int() const { return val; }

преобразование работает только за пределами printf & соиЬ.

 int e=foo;
printf(" %d ",e); //works

1

Решение

Вы не можете перегружать класс, но вы можете использовать оператор преобразования, чтобы он автоматически конвертировал в различные типы в соответствии с ожидаемыми параметрами в этом контексте. В вашем случае, как val является int, вы бы перегружали конвертацию в int как это:

operator int() const { return val; }

Теперь везде, где int требуется, и вы предоставляете foo, это преобразование применяется.

Есть некоторые ограничения. Например, если вы передаете foo в шаблон функции, где тип соответствующего аргумента является общим, в этом месте преобразование не будет. Преобразование также не повлияет на другие выражения, которые не поддерживают тип. В качестве примера, если f это тип foo, затем &f всегда будет иметь тип foo*не int*, Для большинства практических применений все это именно то, что вам нужно. Но я считаю, что C-стиль Variadic printf это как раз тот случай, когда нет четко определенного ожидаемого типа. Лучше использовать вызов в стиле C ++ или явное приведение static_cast<int>(f),

Если ни то, ни другое не приемлемо для вас, то вы попадаете в беду: логика C ++ не может сделать вывод, что вам требуется int здесь, просто потому что вы включили %d в некоторых строковых константах. Преобразование типов выполняется во время компиляции, тогда как интерпретация строк формата выполняется во время выполнения (кроме случаев, когда генерируются предупреждения, как, например, делает gcc). Компилятор не будет знать, какого типа должен быть этот аргумент, поэтому он не будет знать, какое преобразование выполнить, поэтому вы должны каким-то образом ему помочь.

Пока это int val является единственным членом fooи в этом классе нет виртуальных функций, и там нет базового класса с какими-либо членами данных или виртуальной функции, структуры памяти объекта класса foo обычно будет таким же, как и у простого целого числа. Это означает, что нетипизированный стиль C printf не сможет заметить разницу, даже без какого-либо преобразования вообще. Но полагаться на это действительно плохой стиль, поэтому я бы посоветовал не использовать это.

4

Другие решения

Не перегружайте запятыми или чем-то таким ужасным. printf имеет параметр многоточия, поэтому он принимает все, что вы подаете на него, вы должны убедиться, что то, что вы предоставляете, является правильным. Будь проще:

class foo
{
....
//some constructors here set val=34
....
private:
int val;
public:
int value()
{
return val;
}
};

int main()
{
foo bar;
printf("  %d ", bar.value());   //you get value of bar.val
}

printf не вызывает никаких операторов на вашей панели (включая операторов преобразования), поэтому они вам не помогут. Даже если бы вы имели operator int() вы все равно должны написать это так:

    printf("  %d ", (int)bar);   //you get value of bar.val

Это не намного лучше выглядит. Или даже:

    printf("  %d ", +bar);   //you get value of bar.val

Самое запутанное.

2

Нет, это невозможно.

Во-первых, оператор запятой здесь не применяется, потому что запятая используется для разделения аргументов printf, которая имеет приоритет над запятой, используемой в качестве оператора.

Добавление оператора преобразования не помогает, потому что объявление printf

printf(const char *,...);

Это означает, что компилятор не знает, каким должен быть тип параметров (кроме первого), поэтому он не будет выполнять никакого преобразования.

2
По вопросам рекламы [email protected]