Я хотел бы смочь сделать это:
class myInt : public int
{
};
Почему не может я?
Почему я хотел бы? Более сильный ввод. Например, я мог определить два класса intA
и intB
, которые позволяют мне сделать intA + intA
или intB + intB
, но нет intA + intB
.
"Ints не являются классами". И что?
"Ints не имеют никаких членских данных". Да они делают, у них есть 32 бита, или что бы то ни было.
"Ints не имеют никаких функций членства". Ну, у них есть целый набор операторов как +
и -
.
Если вы используете 0,9 бета-версия Cocos2D имеет действительно простое обнаружение касания для кокозонов. Настоящая красота этого нового обнаружения состоит в том, что она хорошо справляется с несколькими сенсорными отслеживанием.
Пример этого можно найти здесь
http://code.google.com/p/cocos2d-iphone/source/browse/#svn/trunk/tests/toushestest
-121--2790240-Комментарий Нила довольно точно. Bjarne упомянул рассмотрение и отклонение этой точной возможности 1 :
Синтаксис инициализатора используется для незаконно для встроенных типов. Позволять это, я представил понятие, которое Встроенные типы имеют конструкторы и деструкторы. Например:
int a (1); // Ошибка до 2,1, теперь инициализирует A до 1
Я считал, что расширяя это понятие Разрешить вывод от встроенных классов и явная декларация встроенного Операторы для встроенных типов. Тем не мение, Я сдержал себя.
позволяет вывод от
int
не на самом деле дать программист C ++ что-нибудь значительно новое по сравнению с УчастникINT
. Это в первую очередь, потому чтоint
не имеет любые виртуальные функции для производных класс для переопределения. Более серьезно Хотя правила конверсии C так хаотичный, который притворяется, чтоint
,Короткое
и т. Д., Хорошо себя ведет Обычные классы не собираются работать. Они либо C совместимы, либо они подчиняться относительно хорошо поведенскому C ++ Правила для классов, но не обоих.
Насколько комментарий производительность оправдывает, не делая int класс, он (по крайней мере, в основном) false. В SmallTalk все виды являются классами - но почти все реализации SmallTalk имеют оптимизацию, поэтому реализация может быть по существу идентична, как вы сделаете работу не класса. Например, класс SmallInteger представляет собой 15-битное целое число, а сообщение «+» жестко закодируется в виртуальную машину, поэтому, даже если вы можете получить от SmallInteger, он все еще дает производительность, аналогичную встроенному типу ( Хотя SmallTalk достаточно отличается от C ++, что прямые сравнения производительности сложно и вряд ли значит значит много).
Один бит, который «потрачен» в реализации SmallTalk от SmandInteger (причина, по которой оно только представляет 15 бит вместо 16), вероятно, не потребуется в C или C ++. SmallTalk немного похоже на Java - когда вы «определяете объект», вы действительно просто определяете указатель на объект, и вам приходится динамически выделять объект для него, чтобы указать на. То, что вы манипулируете, проходите к функции в качестве параметра и т. Д. Всегда только указатель, а не сам объект.
Это , как меньшинтер реализован, хотя - в его случае они помещают целочисленное значение непосредственно в то, что обычно будет указателем. Чтобы различать меньшинцы и указателем, они заставляют выделять все объекты в даже границах байтов, поэтому LSB всегда ясен. SmallInteger всегда имеет набор LSB.
Однако большинство этого необходимо, однако, потому что SmallTalk динамически набирается - он должен быть в состоянии вывести тип, глядя на саму по себе значение, и SmallInteger в основном использует этот LSB в качестве типового тега. Учитывая, что C ++ статически набирается, никогда не нужно вывести тип из значения, поэтому вам, вероятно, не нужно «отпустить», чтобы он бил на тег.
1. В Дизайн и эволюция C ++ , §15.11.3.
Если я помню, это была главная или одна из - основные причины C ++ не считались настоящим ориентированным объектом языком. Java люди сказали бы: «В Яве все является объектом»;)
Посмотрите на Albow , PGU или Ocemp .
-121--2943716-Вы можете использовать WinINET API для достижения этой цели; WinINET определяет основные параметры настройки Интернета для большинства/многих приложений Windows и может использоваться для определения информации прокси. С учетом этого можно создать прокси, который отклоняет все запросы, кроме сообщений.
-121--4904051-В C++ встроенные типы не являются классами.
Более общее, чем тот факт, что «int представляет собой примитив»: INT
INT - это Scalar , в то время как классы агрегат типы. Скаляр - это атомное значение, а совокупность - это что-то с членами. Наследование (по крайней мере, так как он существует в C ++), имеет смысл для агрегатального типа, потому что вы не можете добавить членов или методов скаляров - по определению, у них нет ни каких-либо членов.
То, что другие сказали, является правдой ... INT
является примитивным в C ++ (очень похоже на C #). Тем не менее, вы можете добиться того, что вы хотели, просто строительство класса вокруг INT
:
class MyInt
{
private:
int mInt;
public:
explicit MyInt(int in) { mInt = in; }
// Getters/setters etc
};
Вы можете унаследовать от того, что все, что вы веселитесь.
Что значит унаследовать от INT?
«int» не имеет функций члена; Он не имеет данных члена, это на 32 (или 64) битовое представление в памяти. У него нет собственного VTable. Все, что он «имеет» (оно на самом деле даже не владеет) - некоторые операторы, такие как + - / *, которые действительно более глобальные функции, чем функции членов.
Скотт Мейер ( Эффективное C ++ имеет очень эффективное и мощное решение вашей проблемы выполнения сильных типов базовых типов в C ++ , И это работает так:
Сильная набравка - это проблема, которая может быть адресована и оценена при компиляции , что означает, что вы можете использовать ординалы (слабые набравшими) для нескольких типов во время выполнения Развернутые приложения и используют специальную фазу компиляции для утилизации неподходящих комбинаций типов при компиляционном времени.
#ifdef STRONG_TYPE_COMPILE
typedef time Time
typedef distance Distance
typedef velocity Velocity
#else
typedef time float
typedef distance float
typedef velocity float
#endif
Вы тогда определяете ваше время
, Масса
, Расстояние
Быть классами со всеми (и только) соответствующими операторами, перегруженными в соответствующие операции. В псевдокоде:
class Time {
public:
float value;
Time operator +(Time b) {self.value + b.value;}
Time operator -(Time b) {self.value - b.value;}
// don't define Time*Time, Time/Time etc.
Time operator *(float b) {self.value * b;}
Time operator /(float b) {self.value / b;}
}
class Distance {
public:
float value;
Distance operator +(Distance b) {self.value + b.value;}
// also -, but not * or /
Velocity operator /(Time b) {Velocity( self.value / b.value )}
}
class Velocity {
public:
float value;
// appropriate operators
Velocity(float a) : value(a) {}
}
Как только это сделано, ваш компилятор скажет вам какие-либо места, которые вы нарушили правила, закодированные в вышеуказанных классах.
Я позволю вам выработать остальные детали самостоятельно или купить книгу.
Никто не упомянул, что C ++ был разработан, чтобы иметь (в основном) обратной совместимости с C, чтобы ослабить путь обновления для кодов C, следовательно, struct
Уровень по умолчанию для всех участников Public и т. Д.
Иметь INT
в качестве базового класса, в качестве базового класса, который вы могли бы переопределить, будет в основном усложнять это правило, и сделать реализацию компилятора адскую, и если вы хотите, чтобы существующие кодировщики и поставщики компилятора поддержали ваш язык Fledling вероятно, не стоит усилий.
Ну, вам действительно не нужно наследовать все, что не имеет никаких функций виртуальных участников. Так что даже если INT
были классом, не будет плюс над композицией.
Так сказать, виртуальное наследование является единственной реальной причиной, по которой вам нужно наследование на наследство; Все остальное просто спасает вас массы ввода времени. И я не думаю, что int
класс / тип с виртуальными участниками будет самым важным представителем в мире C ++. По крайней мере, для вас каждый день int
.
Поскольку int - это родной тип, а не класс
Редактировать: перемещение моих комментариев в мой ответ.
Это происходит от наследия C и что именно, примитивы представляют собой. Примитив в C ++ - это просто набор байтов, которые мало значат, за исключением компилятора. Класс, с другой стороны, имеет функциональную таблицу, и как только вы начнете идти по поводу наследства и виртуального наследования, то у вас есть VTable. Никто из этого не присутствует в приведенном в примибильном, и, делая его присутствующим, что вы бы а) разбили много C-кода, который предполагает, что INT - это только 8 байтов, а B) Сделать программы намного больше памяти.
Подумайте об этом другим способом. INT / FLOAT / CHAR не имеет никаких данных или методов данных. Подумайте о примитивах как кварках - они являются строительными блоками, которые вы не можете подразделить, вы используете их, чтобы сделать более крупные вещи (извинения, если моя аналогия немного выключена, я не знаю достаточно физики частиц)
Если OP действительно хочет понять, почему C ++ - это способ, то он должен получить копию книги STROUSTUP «Дизайн и эволюцию C ++». Это объясняет обоснование этого и многих других проектных решений в первые дни C ++.
int - порядковый тип, а не класс. Почему вы хотите?
Если вам нужно добавить функциональность на «int», рассмотрите возможность построения совокупного класса, в котором есть целочисленное поле, а также методы, которые подвергают любые дополнительные возможности, которые вам требуют.
Обновление
@OP «ints не классы» так?
Наследование , полиморфизм и инкапсуляция являются ключевыми камнями объектно-ориентированного дизайна . Ни одно из этих вещей не распространяется на порядковые типы. Вы не можете наследовать от INT, потому что это просто кучка байтов и не имеет кода.
Ints, Chars и другие порядковые типы не имеют таблиц метода , поэтому нет способа добавлять методы или переопределить их, что на самом деле является сердцем наследования.
Как и другие мои слова, не может быть сделано, так как int - это примитивный тип.
Я понимаю мотивацию, однако, если это для более сильного набора текста. Для C++0x даже было предложено, чтобы для этого было достаточно специального типа typedef (но это было отклонено?).
Возможно, чего-то можно было бы добиться, если бы вы сами предоставили базовую обертку. Например, что-то вроде следующего, что, надеюсь, легально использует любопытно повторяющиеся шаблоны, и требует только получения класса и предоставления подходящего конструктора:
template <class Child, class T>
class Wrapper
{
T n;
public:
Wrapper(T n = T()): n(n) {}
T& value() { return n; }
T value() const { return n; }
Child operator+= (Wrapper other) { return Child(n += other.n); }
//... many other operators
};
template <class Child, class T>
Child operator+(Wrapper<Child, T> lhv, Wrapper<Child, T> rhv)
{
return Wrapper<Child, T>(lhv) += rhv;
}
//Make two different kinds of "int"'s
struct IntA : public Wrapper<IntA, int>
{
IntA(int n = 0): Wrapper<IntA, int>(n) {}
};
struct IntB : public Wrapper<IntB, int>
{
IntB(int n = 0): Wrapper<IntB, int>(n) {}
};
#include <iostream>
int main()
{
IntA a1 = 1, a2 = 2, a3;
IntB b1 = 1, b2 = 2, b3;
a3 = a1 + a2;
b3 = b1 + b2;
//a1 + b1; //bingo
//a1 = b1; //bingo
a1 += a2;
std::cout << a1.value() << ' ' << b3.value() << '\n';
}
Но если вы воспользуетесь советом просто определить новый тип и перегрузить операторы, вы можете взглянуть на Boost.Operators
Почему я хочу? Сильнее печатать. Например, я мог бы определить два класса Inta и INTB, что позвольте мне сделать Inta + Inta или INTB + INTB, но не Inta + Intb.
Это не имеет смысла. Вы можете сделать все это без наследства от чего-либо. (А с другой стороны, я не вижу, как вы могли бы достичь его, используя наследство.) Например,
class SpecialInt {
...
};
SpecialInt operator+ (const SpecialInt& lhs, const SpecialInt& rhs) {
...
}
Заполните пробелы, и у вас есть тип, который решает вашу проблему. Вы можете сделать Specialint + Specialint
или int + int
, но Специализируется + INT
не будет компитен, точно так, как вы хотели.
С другой стороны, если мы притворяемся, что наследование от INT было законно, а наше специальнику
, полученных из int
, то специальностью + INT
будет компилируйте. Наследование приведет к точной проблеме, которую вы хотите избежать. Не Унаследование легко избежать проблемы.
«INT не имеет никаких функций-членов». Ну, у них есть целый кучу операторов, таких как + и -.
Это не являются функциями члена, хотя.
Это связано с тем, как элементы хранятся в памяти. INT в C ++ является неотъемлемым типом, как упомянуто в другом месте и составляет всего 32 или 64 бита (слово) в памяти. Однако объект хранится по-разному в памяти. Обычно он хранится на куче, и он имеет функциональность, связанные с полиморфизмом.
Я не знаю, как это объяснить это лучше. Как бы вы наследовали от номера 4?
Почему вы не можете наследовать от INT, даже если вы можете захотеть?
Нет функциональной причины, по которой вы не должны быть в состоянии (на произвольном языке) наследовать от порядковых типов, таких как Int или char, или char * и т. Д. Некоторые языки, такие как Java и Objective-C, фактически предоставляют версии базового типа класса / объекта (в штучной упаковке), чтобы удовлетворить эту потребность (а также для решения некоторых других неприятных последствий Порядковые типы не являются объектами):
language ordinal type boxed type,
c++ int ?
java int Integer
objective-c int NSNumber
Но даже Java и Objective-C сохраняют свои порядковые типы для использования ... Почему?
Простые причины являются производительность и потребление памяти. Как правило, порядковый тип обычно можно построить и передаваться по значению всего за один или два инструкции x86 и только потребляет несколько байтов в худшем случае. Класс обычно не может - это часто использует 2 раза или более как большая память, а манипулирование его значением может принимать много сотен циклов.
Это означает, что программисты, которые понимают, что это, как правило, используют порядковые типы для реализации выполнения или программного обеспечения для использования производительности или использования памяти, и потребуют, чтобы разработчики языка поддерживают базовые типы.
Следует отметить, что немногие языки не имеют порядковых типов, в частности, динамические языки, такие как Perl
, который почти полностью зависит от вариационного типа, что является чем-то еще, и акции некоторые из накладных расходов классов.
Вы можете получить то, что хотите, с помощью строгих typedefs. См. BOOST_STRONG_TYPEDEF