Селекторы в Objective C?

Проблемы:

1) Если функция view определена как:

void view(std::ostream output, std::string text) // (1)
{
    output << text;
}

И используется:

view(std::cout, "Hello, World!"); // (2)

Тогда сообщение об ошибке задается компилятором:

В MSVC:

error C2280: 'std::basic_ostream>::basic_ostream(const std::basic_ostream> &)': attempting to reference a deleted function

blockquote>

GCC:

error: use of deleted function 'std::basic_ostream<_CharT, _Traits>::basic_ostream(const std::basic_ostream<_CharT, _Traits>&) [with _CharT = char; _Traits = std::char_traits]'

blockquote>

Clang:

error: call to deleted constructor of 'std::ostream' (aka 'basic_ostream')

blockquote>

2) Для объявления

std::ostream os;
[1137 ] Отображается следующее сообщение об ошибке:

MSVC:

error C2512: 'std::basic_ostream>': no appropriate default constructor available

blockquote>

GCC:

[ 1110]

blockquote>

Clang:

error: calling a protected constructor of class 'std::basic_ostream'

blockquote>

Причина:

Это все в соответствии со спецификацией std :: basic_ostream

Нет определения для конструктора по умолчанию - поэтому переменная типа std::ostream не может быть создана без конкретных параметров конструктора. [ 1145]

И, как говорится в C ++ Reference, о конструкторе копирования std :: basic_ostream :

Конструктор копирования защищен и удален. Выходные потоки не копируются.

blockquote>

Объяснение:

1) Итак, проблема в том, что в (2) параметр std::cout был передан функции, которая определена в (1) скопировать std::ostream в переменную output.

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

2) В случае создания переменной os - она ​​не дает никаких параметров конструктора, нет конструктора по умолчанию, поэтому компилятор выдает сообщение об ошибке.


Как это исправить?

1) В объявлении функции измените определение, чтобы в качестве параметра взять ссылку (&) на std::ostream:

[113 ]

Это позволяет ему использовать оригинальный объект вместо копирования (что копирование запрещено).


2) Если требуется переменная, то также следует использовать ссылку;

std::ostream& out = std::cout;

121
задан Cœur 5 June 2019 в 17:04
поделиться

6 ответов

Вы должны быть очень осторожны с именами методов. В этом случае имя метода просто « lowercaseString », а не « lowercaseString: » (обратите внимание на отсутствие двоеточия). Вот почему вы получаете NO , так как объекты NSString отвечают на сообщение lowercaseString , но не на lowercaseString: Сообщение.

Как узнать, когда нужно добавить двоеточие? Вы добавляете двоеточие к имени сообщения, если добавляете двоеточие при его вызове, что происходит, если он принимает один аргумент. Если он принимает нулевые аргументы (как в случае с lowercaseString ), то двоеточие отсутствует. Если требуется более одного аргумента, вы должны добавить дополнительные имена аргументов вместе с их двоеточиями, как в , сравните: options: range: locale: .

Вы также можете посмотреть на документацию и отметьте наличие или отсутствие висящей ободочной кишки.

178
ответ дан 24 November 2019 в 01:32
поделиться

Селекторы являются эффективным способом ссылки на методы непосредственно в скомпилированном коде - компилятор - это то, что фактически присваивает значение в SEL.

Другие уже охватили вторую часть вашего q, в конце ':' совпадает с сигнатурой, отличной от той, которую вы ищете (в этом случае эта сигнатура не существует).

11
ответ дан 24 November 2019 в 01:32
поделиться

Не думайте о двоеточии как о части имени функции, думайте о ней как о разделителе, если вы не У вас нет ничего, что можно отделить (никакого значения для функции), тогда вам это не нужно.

Я не уверен, почему, но все эти вещи в ОО, кажется, чужды разработчикам Apple. Я настоятельно рекомендую взять Visual Studio Express и поиграть с этим тоже. Не потому, что одно лучше другого, просто это хороший способ взглянуть на проблемы дизайна и способы мышления.

Как и

introspection = reflection
+ before functions/properties = static
- = instance level

Всегда хорошо смотреть на проблему по-разному, и программирование - это главная загадка.

1
ответ дан 24 November 2019 в 01:32
поделиться

Это потому, что вы хотите @selector (lowercaseString) , а не @selector (lowercaseString :) . Есть небольшая разница: второй подразумевает параметр (обратите внимание на двоеточие в конце), но - [NSString lowercaseString] не принимает параметр.

10
ответ дан 24 November 2019 в 01:32
поделиться

Метод NSString - lowercaseString (0 аргументов), а не lowercaseString: (1 аргумент).

3
ответ дан 24 November 2019 в 01:32
поделиться

В этом случае имя селектора неправильно. Двоеточие здесь является частью сигнатуры метода; это означает, что метод принимает один аргумент. Я считаю, что вы хотите

SEL sel = @selector(lowercaseString);
5
ответ дан 24 November 2019 в 01:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: