[c++] почему запрещены virtual static методы?
а как ты себе их представляешь? этож в концепцию ооп не вписывается
Да, есть, но ты его не поймёшь, наверное, уже никогда, раз сейчас не понимаешь =)
Слабо объяснить?
---
...Я работаю антинаучным аферистом...
---
...Я работаю антинаучным аферистом...
ну зачем ты так, может чуви с геофака, хочет прогроммировать научиться
ты ему лучше книжку про ооп посоветуй, для чайников которая
А тебе? =)
А я не знаю.
---
...Я работаю антинаучным аферистом...
---
...Я работаю антинаучным аферистом...
объясняю на пальцах, что такое ООп: есть объект, у объекта есть методы, все они виртуальные, а еще есть статические методы, с объектами связаны чисто формально и вообще к ООП никакого отношения не имеют 
Ну видишь ли, раз он уже знает слова "static" и "virtual", и даже знает, что написано в стандарте, значит, он уже читал книжку.
Кстате, при чём тут концепция ООП? static не может быть virtual, потому что такого не может быть никогда!
Кстате, при чём тут концепция ООП? static не может быть virtual, потому что такого не может быть никогда!
Что означает "виртуальные"? Мнимые, что ли?
Начерта они тогда?
---
...Я работаю антинаучным аферистом...
Начерта они тогда?
---
...Я работаю антинаучным аферистом...
> static не может быть virtual, потому что такого не может быть никогда!
Credo.
---
...Я работаю антинаучным аферистом...
Credo.
---
...Я работаю антинаучным аферистом...
=)
А ещё есть такой Вирт, он тоже мнимый
А ещё есть такой Вирт, он тоже мнимый
не мнимые, а полиморфные 
"Полиморфные" --- это как? С изменяемой сигнатурой?
---
...Я работаю антинаучным аферистом...
---
...Я работаю антинаучным аферистом...
не, сигнатура как раз должна совпадать
почему ж не вписывается?
static - не зависят от объекта
virtual - вызываются члены у соответствующего объекту класса
почему хочу статику ясно - не использует нестатических членов класса, данные объекта короч
почему виртуальную - чтобы можно было вызвать this->method в родительском классе и не париться
я где-то не прав?
static - не зависят от объекта
virtual - вызываются члены у соответствующего объекту класса
почему хочу статику ясно - не использует нестатических членов класса, данные объекта короч
почему виртуальную - чтобы можно было вызвать this->method в родительском классе и не париться
я где-то не прав?
чо то не понял, ты что хочешь?
для примера:
вот хочу, чтобы в классе-потомке можно было определить статическую функцию IsValid и чтобы она подставлялась в C::Init
class P
{
virtual static bool IsValid (int data) = 0;
void Init ;
}
void P::Init
{
if (!IsValid (0
throw E ;
...
}
class C: P {...};
вот хочу, чтобы в классе-потомке можно было определить статическую функцию IsValid и чтобы она подставлялась в C::Init
что он хочет - это понятно, чтобы, например, передавать указатель на обычную функцию внутрь другой через классовую оболочку (интерфейс). Надо сказать, вполне разумная идея. Видимо, просто её было лень реализовывать, потому как идейно это может быть и не очень правильно - всё же статические медоты нужны скорее для того, чтобы функции, нужные внутри класса, не вносили излишнюю путаницу.
ну а зачем тебе IsValid делать статическим то?
>> почему хочу статику ясно - не использует нестатических членов класса, данные объекта короч
Статический метод не привязан к объекту. Ему не передаётся this. А поскольку ему не передаётся this, привязка вызова к конкретному методу (binding) не может осуществляться в рантайме, и всегда осуществляется на этапе компиляции. А virtual относится к процедуре привязки к конкретному методу в рантайме и, соответственно, не имеет никакого смысла.
А всё потому, что в Правильных Языках в принципе запрещено вызывать статические методы у объекта, всегда нужно писать название класса, а в Неправильных можно и так, и так (насколько я помню что порождает некоторое недопонимание.
Вот, даже так можно объяснить: "чтобы можно было вызвать this->method в родительском классе и не париться" - в статическом методе нет this.
Статический метод не привязан к объекту. Ему не передаётся this. А поскольку ему не передаётся this, привязка вызова к конкретному методу (binding) не может осуществляться в рантайме, и всегда осуществляется на этапе компиляции. А virtual относится к процедуре привязки к конкретному методу в рантайме и, соответственно, не имеет никакого смысла.
А всё потому, что в Правильных Языках в принципе запрещено вызывать статические методы у объекта, всегда нужно писать название класса, а в Неправильных можно и так, и так (насколько я помню что порождает некоторое недопонимание.
Вот, даже так можно объяснить: "чтобы можно было вызвать this->method в родительском классе и не париться" - в статическом методе нет this.
чтобы сказать, что он от объекта не зависит
ок, ну а зачем он тебе нужен, как виртуальный тогда?
как такое возможно? тут ведь либо то, либо другое
как такое возможно? тут ведь либо то, либо другое
Да блин, механизм вызова совершенно разный.
1) При вызове обычного метода вызывающий метод передаёт объект, далее по объекту определяется реальный класс, для него осуществляется прогон вверх по дереву наследования до последнего виртуального неабстрактного прототипа который и вызывается, причём в качестве "нулевого параметра" (this) ему передаётся тот объект.
2) При вызове статического метода вызывающий метод никакого объекта не передаёт, вызываемый метод определён на этапе компиляции и нулевого параметра у него просто нет.
1) При вызове обычного метода вызывающий метод передаёт объект, далее по объекту определяется реальный класс, для него осуществляется прогон вверх по дереву наследования до последнего виртуального неабстрактного прототипа который и вызывается, причём в качестве "нулевого параметра" (this) ему передаётся тот объект.
2) При вызове статического метода вызывающий метод никакого объекта не передаёт, вызываемый метод определён на этапе компиляции и нулевого параметра у него просто нет.
А поскольку ему не передаётся this, привязка вызова к конкретному методу (binding) не может осуществляться в рантайме, и всегда осуществляется на этапе компиляцииможет, только не осуществляется, т.к. это не нужно, если писать "класс::метод"
в Правильных Языках в принципе запрещено вызывать статические методы у объектаа что такого?
объект -> класс -> функция
да что ты ему про механизм говоришь, он идею и принцип ооп не понимает
> ок, ну а зачем он тебе нужен, как виртуальный тогда?
> как такое возможно? тут ведь либо то, либо другое
Могу своё понимание выссказать.
Например, в учебных примерах по каким-нибудь чмам часто требуется передать указатель на функцию куда-то. В принципе, логично было бы вместо того, чтобы передавать указатель на функцию, запихивать в функцию указатель на объект, содержащий интерфейс к этой самой функции. Ну а по сколько, нужная нам функция по своей природе такова, что ей не нужны никакие объекты - то логично было бы сделать её статической. Иными словами, подобная конструкция нужна для того, чтобы унифицировать процесс передачи параметров в функцию.
Я на Яве слишком мало писал, поэтому не знаю - как в Яве передать куда-либо указатель на функцию? Как подобное обычно реализовывают?
> как такое возможно? тут ведь либо то, либо другое
Могу своё понимание выссказать.
Например, в учебных примерах по каким-нибудь чмам часто требуется передать указатель на функцию куда-то. В принципе, логично было бы вместо того, чтобы передавать указатель на функцию, запихивать в функцию указатель на объект, содержащий интерфейс к этой самой функции. Ну а по сколько, нужная нам функция по своей природе такова, что ей не нужны никакие объекты - то логично было бы сделать её статической. Иными словами, подобная конструкция нужна для того, чтобы унифицировать процесс передачи параметров в функцию.
Я на Яве слишком мало писал, поэтому не знаю - как в Яве передать куда-либо указатель на функцию? Как подобное обычно реализовывают?
ок, ну а зачем он тебе нужен, как виртуальный тогда?как виртуальный, чтобы родительской функции поставить вызов, а в рантайме уже определять для какого класса вызывать
как такое возможно? тут ведь либо то, либо другое
да, такое не возможно откомпилить. вопрос - по какой причине?
хм, а в яве разве можно передать указатель на функцию?
в твоем примере следует передавать в качестве параметра объект, и у объекта вызывать эту фунцию
в твоем примере следует передавать в качестве параметра объект, и у объекта вызывать эту фунцию
>> может, только не осуществляется, т.к. это не нужно, если писать "класс::метод"
Нет, не может, потому что нет объекта, и, соответственно, нет понятия "реальный тип".
Поясняю на примере:
class A
{
public virtual void Method
{
Console.WriteLine("A");
}
}
class B : A
{
public override void Method
{
Console.WriteLine("B");
base.Method;
}
}
class C : B
{
public override void Method
{
Console.WriteLine("C");
base.Method;
}
}
public static void Main
{
B obj = new C;
obj.Method;
}
Так вот, хотя переменная obj имеет тип B, объект в ней содержащийся имеет тип С, поэтому выведется
C
B
A
Вот.
И ещё раз: в статическом методе нет this. У статического и нестатического метода разное число параметров (имеется в виду те, которые передаются на самом деле).
Я это всё на шарпе пишу, но в плюсах механизм абсолютно тот же самый.
Нет, не может, потому что нет объекта, и, соответственно, нет понятия "реальный тип".
Поясняю на примере:
class A
{
public virtual void Method
{
Console.WriteLine("A");
}
}
class B : A
{
public override void Method
{
Console.WriteLine("B");
base.Method;
}
}
class C : B
{
public override void Method
{
Console.WriteLine("C");
base.Method;
}
}
public static void Main
{
B obj = new C;
obj.Method;
}
Так вот, хотя переменная obj имеет тип B, объект в ней содержащийся имеет тип С, поэтому выведется
C
B
A
Вот.
И ещё раз: в статическом методе нет this. У статического и нестатического метода разное число параметров (имеется в виду те, которые передаются на самом деле).
Я это всё на шарпе пишу, но в плюсах механизм абсолютно тот же самый.
1) При вызове обычного метода вызывающий метод передаёт объект, далее по объекту определяется реальный класс, для него осуществляется прогон вверх по дереву наследования до последнего виртуального неабстрактного прототипа который и вызывается, причём в качестве "нулевого параметра" (this) ему передаётся тот объект.Давай на примере C++. У нас есть объект, среди его данных - указатель на таблицу указателей на виртуальные функции, которая своя для каждого класса. При этом параметры этих функций учитываются на этапе компиляции. Что нам мешает сделать так, чтобы в этой таблице хранились не только функции-члены, но и обычные статические функции? Просто компилятор должен будет учитывать этот момент...
2) При вызове статического метода вызывающий метод никакого объекта не передаёт, вызываемый метод определён на этапе компиляции и нулевого параметра у него просто нет.
Ни в яве, ни в шарпе нельзя передавать указатель на функцию. Для этого используется специальный тип объектов - delegate, которые инкапсулируют указатель на объект и что-то типа указателя на функцию.
А механизм я объясняю потому, что на самом деле кроме механизма ничего и нет =)
А механизм я объясняю потому, что на самом деле кроме механизма ничего и нет =)
> хм, а в яве разве можно передать указатель на функцию?
Судя по тому, что апологеты Явы отсутствие указателей записывают в преимущества языка - наверное, нельзя, но я, повторюсь, слишком поверхностно Яву знаю. Вот мне и интересно, как предлагается решать такую задачу
Судя по тому, что апологеты Явы отсутствие указателей записывают в преимущества языка - наверное, нельзя, но я, повторюсь, слишком поверхностно Яву знаю. Вот мне и интересно, как предлагается решать такую задачу

не понял, к чему этот пример
И ещё раз: в статическом методе нет this. У статического и нестатического метода разное число параметров (имеется в виду те, которые передаются на самом деле).нет this. полностью поддерживаю. но почему по this нельзя определить класс и вызвать соотв. функцию?
короче, скажи абстрактно, что ты хочешь реализовать и я скажу, как это сделать идеологически правильно с точки зрения объектного подхода
или опиши конкретно свой пример, а то я так и не понял, что ты там пытаешься изобразить
так вот, я же привел урезанный пример реальной ситуации
или подробнее пример написать?
вообще, сначала у меня была виртуальная функция и я не парился
потом понял, что она от объекта не зависит, поставил статику, а тут мне руки и скрутили... решил разобраться
или подробнее пример написать?
вообще, сначала у меня была виртуальная функция и я не парился
потом понял, что она от объекта не зависит, поставил статику, а тут мне руки и скрутили... решил разобраться
>как виртуальный, чтобы родительской функции поставить вызов, а в рантайме уже определять для какого класса вызывать
вот это поясни, не понял
вот это поясни, не понял
вот пример: нужно написать функцию вычисления определённого интеграла. Пусть для простоты - интеграл от [0;1], методом прямоугольников (по первой точке число шагов=1000. Функция интегрирования должна получить каким-то образом в качестве параметра функцию, которую нужно интегрировать. Создадим для этой цели интерфейсный класс (ну непонтово просто указатель на функцию передавать)
Надеюсь не накосячил... Идея ясна?
/// интерфейсный класс
class func_int{
public:
static virtual double func(double x)=0;
};
////// реализация
class fuct_1 public func_int{
double func(double x)
{return sin(x);}
};
//// функция интегрирования
double integr(fucn_int *ii)
{
int a;
double res;
for(a=0,res=0; a<1000; a++)
res+=(*ii).func(a*0.001);
return res*0.001;
}
Надеюсь не накосячил... Идея ясна?
Ага. Я понял, что вы имеете в виду, и, наверное, я был не прав.
static описывает свойства метода - передаётся или не передаётся ему this (и, соответственно, имеет ли он доступ к переменным объекта).
В принципе, наверное, можно было было бы сделать процедуру вызова несимметричной - то есть при вызове статического метода у объекта происходят действия связанные с полиморфизмом и наследованием, определяется реальный метод, дальше указатель на объект благополучно забывается и производится вызов.
Но! Это повлекло бы за собой кучу проблем. Во-первых, система становится несимметричной и вообще труднопонимаемой, ИМХО. Ошибка в регистре первой буквы (при стандартном шарповом/жавовском стиле) приводит к тотальному изменению поведения. Далее, вызываемый метод уже не может пользоваться полиморфизмом, вызывая другие методы того же объекта. То есть если для нормальных методов работают обе цепочки
A a = new B;
a.Move =(полиморфизм)=> B.Move =(вызов базового класса)=> A.Move =(вызов)=> A.Paint =(полиморфизм)=> B.Paint =(вызов базового класса)=> A.Paint
a.Paint =(полиморфизм)=> B.Paint =(вызов базового класса)=> A.Paint
То как только они становятся статическими, первая цепочка уже работает не так, а вторая - всё ещё так.
static описывает свойства метода - передаётся или не передаётся ему this (и, соответственно, имеет ли он доступ к переменным объекта).
В принципе, наверное, можно было было бы сделать процедуру вызова несимметричной - то есть при вызове статического метода у объекта происходят действия связанные с полиморфизмом и наследованием, определяется реальный метод, дальше указатель на объект благополучно забывается и производится вызов.
Но! Это повлекло бы за собой кучу проблем. Во-первых, система становится несимметричной и вообще труднопонимаемой, ИМХО. Ошибка в регистре первой буквы (при стандартном шарповом/жавовском стиле) приводит к тотальному изменению поведения. Далее, вызываемый метод уже не может пользоваться полиморфизмом, вызывая другие методы того же объекта. То есть если для нормальных методов работают обе цепочки
A a = new B;
a.Move =(полиморфизм)=> B.Move =(вызов базового класса)=> A.Move =(вызов)=> A.Paint =(полиморфизм)=> B.Paint =(вызов базового класса)=> A.Paint
a.Paint =(полиморфизм)=> B.Paint =(вызов базового класса)=> A.Paint
То как только они становятся статическими, первая цепочка уже работает не так, а вторая - всё ещё так.
class P
{
virtual static bool IsValid (int * data) = 0;
void Init (int *);
};
void P::Init (int * data)
{
if (!IsValid (data
throw E ;
...
}
class C: P
{
static bool IsValid (int * data);
};
bool C::IsValid (int * data)
{
if (data[0] == 1)
return true;
return false;
}
C * c = new C;
теперь при вызове c->Init (data) мне нужно, чтобы использовался его IsValid
ну круто, и чо? фукция integr все пиздато считает, в чем проблема то?
> теперь при вызове c->Init (data) мне нужно, чтобы использовался его IsValid
ну бля, это как раз и есть зависимость, значит IsValid должен быть виртуальным
ну бля, это как раз и есть зависимость, значит IsValid должен быть виртуальным
> ну круто, и чо? фукция integr все пиздато считает, в чем проблема то?
В том то и проблема, что ничего она не считает из-за "static virtual"
В том то и проблема, что ничего она не считает из-за "static virtual"
это как раз и есть зависимость, значит IsValid должен быть виртуальнымэто с самого начала ясно
ясно и то, что IsValid не зависит от объекта...
вот и virtual static
ну как же не зависит, если ты говоришь, что для C он у тебя должен свой быть?
A a = new B;все время впечатление, что производится срезка
а это, наверное, сишарпa.Move =(полиморфизм)=> B.Move =(вызов базового класса)=> A.Move =(вызов)=> A.Paint =(полиморфизм)=> B.Paint =(вызов базового класса)=> A.Paintпример оторван от интерфейса и от жизни, имхо. функции типа сдвинуть или нарисовать уж никак не статические. поэтому пример не понял
a.Paint =(полиморфизм)=> B.Paint =(вызов базового класса)=> A.Paint
То как только они становятся статическими, первая цепочка уже работает не так, а вторая - всё ещё так.

свой, но "C" - это класс, а от объекта "c" не зависит
а функция integr должны быть описана в другом классе, class Calc_my_integr
класс описывает поведение объекта - экземпляра класса
у объекта c, экземпляра класса C должно быть особое поведение, это и значит, что оно описывается его виртуальными методами, в данном случае IsValid
у объекта c, экземпляра класса C должно быть особое поведение, это и значит, что оно описывается его виртуальными методами, в данном случае IsValid
В чем радость статика для виртуального метода? Искать указатель в другой таблице? Сделай конст, коли хочешь построже.
Радость статика в том, что он менее ресурсоёмок при вызове, не нужно лишний указатель передавать, который всё равно не используется. Пример я приводил в треде, когда это может быть полезно... const, вообще говоря, несколько для других целей предназначен.
я уже сделал const и virtual-static walkaround, правда мне не очень нравится
радость статика - в строгости
а значит в возможно лучшей оптимизации
радость статика - в строгости
а значит в возможно лучшей оптимизациикороче, изучать ООП на примере C++ - это неблагодарное занятие, пишите на шарпе, яве, или любом другом правильном яп
Кстати, проясни для несведующих - что в Яве/Шарпе используется вместо C++ Templates?
В Джаве темплейтов как таковых нет. В последней версии там ввели некоторое подобие, дженерики. Раньше этого не было, поэтому шаблонный тип реализовал определённые интерфейсы.
класс описывает поведение объекта - экземпляра классаэто понятно
у объекта c, экземпляра класса C должно быть особое поведение, это и значит, что оно описывается его виртуальными методами, в данном случае IsValid
но мне нужно использовать эту функцию и без объекта... что без статика не получится
да они вообще нахер не нужны в реальной жизни, шаблоны эти
значит тебе надо два метода, один статический, который ты вызываешь из виртуальных
короче, изучать ООП на примере C++ - это неблагодарное занятие, пишите на шарпе, яве, или любом другом правильном япк сожалению, нормальных реализаций известных "правильных яп" не видел
я многого не знаю, но (подчеркиваю) наслышан, что ява - ужасно тормозная штука, а шарп - это вообще промоушн мокрософта, сырой и есть только кривые свободные поделки (какой-то моно, что-ли); он вообще открытый по спецификации?
Ну как знать, как знать... Получается, что есть три главных плюса Явы по стравнению с C++: 1) так нельзя использовать указатели; 2) там нельзя использовать goto; 3) там нельзя использовать шаблоны.
А вообще, в C++ изначально тоже ведь развивались объектные библиотеки, у Borland в версии 3-4 была известная Object Based Class Library, которая в пятой версии была окончательно вытеснена STL. Наверное всё же потому, что STL удобнее и быстрее... Из-за всего этого и трудно сменить C++ на Java/C#.
А вообще, в C++ изначально тоже ведь развивались объектные библиотеки, у Borland в версии 3-4 была известная Object Based Class Library, которая в пятой версии была окончательно вытеснена STL. Наверное всё же потому, что STL удобнее и быстрее... Из-за всего этого и трудно сменить C++ на Java/C#.
Экономия при подъеме RTTI весьма сомнительная 

Я же написал, что в Джаве есть подобие шаблонов: дженерики. Некая модель, которая проверяется на этапе компиляции. Что без шаблонов очень хорошо живётся и они в реальной жизни не нужны - это, конечно, не так. Без них не очень хорошо: и в ненужные моменты в рантайме могут вылетать исключения, и код солидно обрастает try/catch блоками.
ява - ужасно тормозная штука, а шарп - это вообще промоушн мокрософта, сырой и есть только кривые свободные поделкиДжава не тормозная. Тормозные там только GUI библиотеки. В остальном... Надо просто знать, как правильно на ней писать.
Шарп уже давно не сырой. И есть его реализация от Майкрософт. Другое дело, что эта реализация только для винды.
значит тебе надо два метода, один статический, который ты вызываешь из виртуальныхувы, пришлось сделать именно так
но это не гармонично
увы, пришлось сделать именно такНу сам посуди, что ты предлагаешь? Ты пишешь об увеличении скорости работы за счёт применения статических функций. И при этом предлагаешь вызывать их через vtable. Ты выбери что-то одно: либо тебе быстро вызывается си-подобная функция, либо компилятор лазит по vtable. Вообще, я знаю минимум трёх ООП жлобов, которые за идею применения статических функций в таком случае просто бы тебя съели.
но это не гармонично

Джава не тормозная. Тормозные там только GUI библиотеки. В остальном... Надо просто знать, как правильно на ней писать.если я правильно понимаю, чтобы хорошо писать на яве, нужно угадывать, какой С-код стоит за вызовами используемых средств, чтобы вышло оптимальнее...
Шарп уже давно не сырой. И есть его реализация от Майкрософт. Другое дело, что эта реализация только для винды.значит код даже потенциально не переносим... ужас
>> пример оторван от интерфейса и от жизни, имхо. функции типа сдвинуть или нарисовать уж никак не статические. поэтому пример не понял
Объясняю словами. Вот ты пишешь большую прогу на языке, позволяющем несимметричные вызовы - когда статический метод динамически биндится по объекту (кстати, практически никакого выигрыша в производительности не будет, отсутствие передачи лишнего параметра практически не роляет, одна инструкция mov, хуле).
И ты пишешь какой-нибудь статический метод, который предназначен именно для такого вызова, типа с понтом, что вызов должен спускаться вниз по иерархии объектов.
Во-первых, очень велика вероятность ошибиться и вызвать его именно статически.
Во-вторых, ты (или кто-нибудь другой, кто будет писать код на основе твоего) сделает ещё один такой же статический виртуальный метод, который будет вызывать твой. При этом без поллитры нифига не разберёшься, как именно происходит вызов.
Объясняю словами. Вот ты пишешь большую прогу на языке, позволяющем несимметричные вызовы - когда статический метод динамически биндится по объекту (кстати, практически никакого выигрыша в производительности не будет, отсутствие передачи лишнего параметра практически не роляет, одна инструкция mov, хуле).
И ты пишешь какой-нибудь статический метод, который предназначен именно для такого вызова, типа с понтом, что вызов должен спускаться вниз по иерархии объектов.
Во-первых, очень велика вероятность ошибиться и вызвать его именно статически.
Во-вторых, ты (или кто-нибудь другой, кто будет писать код на основе твоего) сделает ещё один такой же статический виртуальный метод, который будет вызывать твой. При этом без поллитры нифига не разберёшься, как именно происходит вызов.
если я правильно понимаю, чтобы хорошо писать на яве, нужно угадывать, какой С-код стоит за вызовами используемых средств, чтобы вышло оптимальнее...Нет, не нужно. Нужно понимать, что такое язык с GC, как создавать поменьше объектов, какие вещи работают принципиально быстрее. Я тебе скажу, что есть очень много задач, в которых за пять минут в лоб написанный код на Джаве или Шарпе обгонит код на С++. До тех пор, пока ты не потратишь на решение той же проблемы на С++ 4-5 часов.
значит код даже потенциально не переносим... ужасКод на Шарпе _потенциально_ вполне переносим. Опять же, С++ не является самым хорошим выбором для переносимости.

Ну сам посуди, что ты предлагаешь? Ты пишешь об увеличении скорости работы за счёт применения статических функций. И при этом предлагаешь вызывать их через vtable. Ты выбери что-то одно: либо тебе быстро вызывается си-подобная функция, либо компилятор лазит по vtable.я предлагаю, чтобы компилятор за меня решил как оптимальнее сделать, раз мне нужны оба свойства
думаю, текущий обход гораздо менее оптимален

вообще, оптимизация у меня на 2-м месте
главное - понятный код, имхо
мне статика в моем случае понадобилась, когда я, уже имея виртуальную IsValid, понял, что она не опирается на данные и что мне нужно ее использовать отдельно от объекта
Вообще, я знаю минимум трёх ООП жлобов, которые за идею применения статических функций в таком случае просто бы тебя съели.

мне статика в моем случае понадобилась, когда я, уже имея виртуальную IsValid, понял, что она не опирается на данные и что мне нужно ее использовать отдельно от объектаНонсенс. Если у тебя IsValid разная для разных объектов, то это автоматически значит, что "ее использовать отдельно от объекта" нельзя. Если она у тебя одна для всех объектов, тогда пихай её в базовый класс. А если функция у тебя "пассивная", то объяви её как const.
>> значит код даже потенциально не переносим... ужас
Да нет, уже очень давно есть оформленный стандарт, и уже где-то год как релизнулась стабильная версия Mono (это типа под никсы в которой в полном объёме есть ASP, и когда я когда-то давно смотрел, чем они занимались, они радостно переходили на C# 2.0, встраивали поддержку винформ и осваивали MSBuild.
Да нет, уже очень давно есть оформленный стандарт, и уже где-то год как релизнулась стабильная версия Mono (это типа под никсы в которой в полном объёме есть ASP, и когда я когда-то давно смотрел, чем они занимались, они радостно переходили на C# 2.0, встраивали поддержку винформ и осваивали MSBuild.
И ты пишешь какой-нибудь статический метод, который предназначен именно для такого вызова, типа с понтом, что вызов должен спускаться вниз по иерархии объектов.возможно
Во-первых, очень велика вероятность ошибиться и вызвать его именно статически.
Во-вторых, ты (или кто-нибудь другой, кто будет писать код на основе твоего) сделает ещё один такой же статический виртуальный метод, который будет вызывать твой. При этом без поллитры нифига не разберёшься, как именно происходит вызов.
дело в том, что я расцениваю static почти как const - просто некий ограничитель внутрянки, который расширяет твои возможности по использованию
иногда слишком большое расширение возможностей приводит к путанице, здесь я полностью согласен
Нонсенс. Если у тебя IsValid разная для разных объектов, то это автоматически значит, что "ее использовать отдельно от объекта" нельзя. Если она у тебя одна для всех объектов, тогда пихай её в базовый класс. А если функция у тебя "пассивная", то объяви её как const.функция IsValid зависит только от дочернего класса, но не от объекта класса
и иногда их надо использовать просто как глобальные функции (ну, в namespace, конечно)
я расцениваю static почти как const - просто некий ограничитель внутрянкиЭто совсем неправильно. Если const значит, что у тебя есть прямой (через this) доступ к членам класса, но ты их не модифицируешь; то static значит, что доступ к членам класса может быть только косвенный (передать объект вручную но при этом ты можешь изменять члены класса. И большая часть программистов в жизни не подумает, что под static ты понимал const.
Да нет, уже очень давно есть оформленный стандарт, и уже где-то год как релизнулась стабильная версия Mono (это типа под никсы в которой в полном объёме есть ASP, и когда я когда-то давно смотрел, чем они занимались, они радостно переходили на C# 2.0, встраивали поддержку винформ и осваивали MSBuild.хорошие новости
все, что я раньше слышал/читал про моно было не таким радужным

мне нужно ее использовать отдельно от объектаХмм. Заведи обертку chk::IsValid(const type_info &)

>>дело в том, что я расцениваю static почти как const - просто некий ограничитель внутрянки, который расширяет твои возможности по использованию
Так вот нет. Создатели плюсов (равно как шарпа и жавы) назвали статическими те функции, которые ВООБЩЕ не привязаны к объектам. И ты очень неправ, что понимаешь слово static не так, как разработчики языка, разработчики компиляторов и вообще основная масса программеров на плюсах
Так вот нет. Создатели плюсов (равно как шарпа и жавы) назвали статическими те функции, которые ВООБЩЕ не привязаны к объектам. И ты очень неправ, что понимаешь слово static не так, как разработчики языка, разработчики компиляторов и вообще основная масса программеров на плюсах
функция IsValid зависит только от дочернего класса, но не от объекта классаЕсли у тебя две разных IsValid у двух разных дочерних классов, то "ее использовать отдельно от объекта" нельзя.
PS И вообще непонятно, в какой задаче удобно иметь функцию, которая вызывается как без объекта, так и с объектом.
Это совсем неправильно. Если const значит, что у тебя есть прямой (через this) доступ к членам класса, но ты их не модифицируешь; то static значит, что доступ к членам класса может быть только косвенный (передать объект вручную но при этом ты можешь изменять члены класса. И большая часть программистов в жизни не подумает, что под static ты понимал const.что значит "совсем"?
различие я понимаю, но ты ведь не написал, для чего это используется...
я ведь могу опустить static и const - ничего плохого не будет, если я не использовал этих "подсказок" - в этом я вижу сходство
спецификаторы позволяют шире использовать методы, но ставят ограничения на код
Так вот нет. Создатели плюсов (равно как шарпа и жавы) назвали статическими те функции, которые ВООБЩЕ не привязаны к объектам. И ты очень неправ, что понимаешь слово static не так, как разработчики языка, разработчики компиляторов и вообще основная масса программеров на плюсахтак и не понял, что именно я понимаю неправильно?

что значит "совсем"?Даже в смысле использования совсем не верно. Модификатор const пишут, когда у тебя функция не изменяет внутренности объекта. Это чтобы программист понял, что GetSize у динамического массива не сотрёт его содержимое, например.
различие я понимаю, но ты ведь не написал, для чего это используется...
я ведь могу опустить static и const - ничего плохого не будет, если я не использовал этих "подсказок" - в этом я вижу сходство
спецификаторы позволяют шире использовать методы, но ставят ограничения на код
Модификатор static ставят тогда, когда функция никоим образом не привязана к поведению объекта. При этом она может получать объект извне и модифицировать его на своё усмотрение. Типичный пример для таких функций: создание экземпляров класса.
так и не понял, что именно я понимаю неправильно?Ты пытаешься использовать статическую функцию в том случае, когда её работа зависит от объекта.
Если у тебя две разных IsValid у двух разных дочерних классов, то "ее использовать отдельно от объекта" нельзя.можно. я предлагаю использовать со спецификатором класса (это дает статик) или резолвить в теле метода родительского класса (это вирчуал) - вот и все (т.е. в зависимости от применения)
фишка в том, что статик и вирчуал - вещи абсолютно параллельные!
И вообще непонятно, в какой задаче удобно иметь функцию, которая вызывается как без объекта, так и с объектом.она вызывается с объектом только для определения класса, из которого эту функцию вызывать
Блиа, тебе ещё в самом начале треда Ахтох нопейсал, что статические методы не привязаны к объектам, а привязаны к классам, и ООП-фишки типа полиморфизма на них просто не действуют. Так это понимают вообще ВСЕ. Ты этого не понимаешь.
можно. я предлагаю использовать со спецификатором класса (это дает статик) или резолвить в теле метода родительского класса (это вирчуал) - вот и все (т.е. в зависимости от применения)Фишка в том, что статик и виртуал вещи абсолютно перпендикулярные. Виртуальная функция опирается на объект, статическая - нет.
фишка в том, что статик и вирчуал - вещи абсолютно параллельные!
Даже в смысле использования совсем не верно. Модификатор const пишут, когда у тебя функция не изменяет внутренности объекта. Это чтобы программист понял, что GetSize у динамического массива не сотрёт его содержимое, например.я вижу главное применение этих двух в том, чтобы компилятор понял что-то, а потом уж программист
Модификатор static ставят тогда, когда функция никоим образом не привязана к поведению объекта. При этом она может получать объект извне и модифицировать его на своё усмотрение. Типичный пример для таких функций: создание экземпляров класса.
если бы конст и статик не давали преимуществ (вызов для константного объекта и без объекта то их попросту ленились бы использовать
я вижу главное применение этих двух в том, чтобы компилятор понял что-то, а потом уж программистНет, ты опять недопонимаешь. Есть необходимость: например, создание первого экземпляра главного класса программы происходит в статической функции. Или если тебе нужно контролировать процесс создания классов: можно объявить конструктор протектедом, и позволять создавать класс только через вызов статической функции.
если бы конст и статик не давали преимуществ (вызов для константного объекта и без объекта то их попросту ленились бы использовать
Блиа, тебе ещё в самом начале треда Ахтох нопейсал, что статические методы не привязаны к объектам, а привязаны к классам, и ООП-фишки типа полиморфизма на них просто не действуют. Так это понимают вообще ВСЕ. Ты этого не понимаешь.я понимаю, что так есть
не понимаю почему?
если уж разрешили использовать this->static_method, так вызывайте правильный метод!
я вижу главное применение этих двух в том, чтобы компилятор понял что-то, а потом уж программистЗдесь ты зря так. Static - даёт преимущества тем, что не передаётся указатель на объект, хотя преимущество здесь - невелико обычно. Декларативное - тоже минимально, впрочем.
если бы конст и статик не давали преимуществ (вызов для константного объекта и без объекта то их попросту ленились бы использовать
Const же - исключительно декларативен, для программиста, компилятор разве что не даст сделать явной ошибки. Но в другом функции с const и обычное - ничем не отличаются.
Нет, ты опять недопонимаешь. Есть необходимость: например, создание первого экземпляра главного класса программы происходит в статической функции. Или если тебе нужно контролировать процесс создания классов: можно объявить конструктор протектедом, и позволять создавать класс только через вызов статической функции.ну так это все подходит под то, что я написал
есть необходимость - люди ставят спецификаторы и все
что же я недопонимаю?
я вижу главное применение этих двух в том, чтобы компилятор понял что-то, а потом уж программист
если бы конст и статик не давали преимуществ (вызов для константного объекта и без объекта то их попросту ленились бы использовать
ну так это все подходит под то, что я написалТак ты определись: необходимость для программиста или чтобы комплятор что-то понял. Не ленятся использовать как правило static именно из-за того, что он не привязан к объекту. И каково бы ни было описание вызова статического метода, он (метод) всё равно не связан с объектом.
есть необходимость - люди ставят спецификаторы и все
что же я недопонимаю
Static - даёт преимущества тем, что не передаётся указатель на объект, хотя преимущество здесь - невелико обычно. Декларативное - тоже минимально, впрочем.разве я не о том же написал: "преимуществ (вызов ... без объекта)"?
Const же - исключительно декларативен, для программиста, компилятор разве что не даст сделать явной ошибки. Но в другом функции с const и обычное - ничем не отличаются.ага. именно поэтому я удивлялся сообщениям компилятора на ранней стадии изучения плюсов, когда он не давал мне вызвать не const функцию на константном объекте
ошибка хоть и явная, ее надо исключать
Нет, я не понимаю, о чём мы говорим... Вызов статической функции происходит без объекта, в то время как вызов обычной - с передачей указателя на уже созданный объект. В этом и есть главный плюс статической функции. Тут до меня дошло, в чём проблема с витруальной статической функцией (я тормозил): Смотри. Есть объект, уже созданный - принципиально то, что указатель на таблицу виртуальных функций - это один из элементов этого объекта! То есть, не создав объект, мы не можем узнать, где находится таблица виртуальных функций, и из-за этого не можем вызвать эту самую статическую виртуальную функцию без объекта. То есть, теоретически это дело можно обойти, но дополнительная работа - слишком большая, и оно того не стоит.
Так ты определись: необходимость для программиста или чтобы комплятор что-то понял.понимание компилятора влечет запреты и необходимость для программиста
Господи, ты уже в третий раз повторил то, что сначала было сказано Ахтохом, затем Fj и мной. Ладно, более детально это уже не разжевать. 

понимание компилятора влечет запреты и необходимость для программистаПричину и следствие местами не меняй. Это программисту нужно какое-то поведение. И он говорит компилятору, каким это поведение должно быть.
Тут до меня дошло, в чём проблема с витруальной статической функцией (я тормозил): Смотри. Есть объект, уже созданный - принципиально то, что указатель на таблицу виртуальных функций - это один из элементов этого объекта! То есть, не создав объект, мы не можем узнать, где находится таблица виртуальных функций, и из-за этого не можем вызвать эту самую статическую виртуальную функцию без объекта. То есть, теоретически это дело можно обойти, но дополнительная работа - слишком большая, и оно того не стоит.это понятно, но я ведь делаю не так
у меня фактически два применения функции, не связанных друг с другом
1. отдельно от всего - тогда C::IsValid - вопросов нет
2. внутри функции род. класса P, т.е. this->IsValid - т.е. уже объект есть (this) и у него можно посмотреть таблицу
это понятно, но я ведь делаю не такЁлы палы. Тебе уже сколько раз сказали? Ну нету привязки к объекту при вызове this->IsValid если IsValid статическая. Понимаешь? В этом и есть смысл static. Джава или Шарп не дадут тебе так написать вообще, и это правильно. Жаль, что в С++ нету ограничения, оно сбивает с толку новичков.
у меня фактически два применения функции, не связанных друг с другом
1. отдельно от всего - тогда C::IsValid - вопросов нет
2. внутри функции род. класса P, т.е. this->IsValid - т.е. уже объект есть (this) и у него можно посмотреть таблицу
Ты же предлагаешь фактически, чтобы в некоторых случаях static функции опирались на объект. В этом и есть полное противоречие.
Причину и следствие местами не меняй. Это программисту нужно какое-то поведение. И он говорит компилятору, каким это поведение должно быть.но предварительно программисту не дал компилятор что-то сделать и он полез менять спецификаторы
так что я не меняю, просто у тебя вторая часть цепочки
Ты не понял. Чувак говорит о том, что когда у нас уже ЕСТЬ объект, можно засунуть ему в vmt указатели на статические методы тоже. И обрабатывать вызовы с использованием полиморфизма, а потом просто не передавать указатель на объект.
Да, это можно сделать.
Но код в результате превратится в спагетти.
Да, это можно сделать.
Но код в результате превратится в спагетти.
Да мы это всё уже давно поняли. Пытаемся ему втолковать, в чём сакральный смысл слова static. 

Ну нету привязки к объекту при вызове this->IsValid если IsValid статическая. Понимаешь? В этом и есть смысл static.Понимаю. Ну вот ты, здравый человек, когда тебе напишут this->IsValid ты какую из объявленных статических функций вызовешь?
Жаль, что в С++ нету ограничения, оно сбивает с толку новичков.+1
> 2. внутри функции род. класса P, т.е. this->IsValid - т.е. уже объект есть (this) и у него можно посмотреть таблицу
Можно... Но всё же, это лишняя работа, некоторая дополнительная путаница... То есть "овчинка не стоит выделки", я так думаю. Я могу описать ситуации, когда подобное будет удобнее своей наглядностью...
Можно... Но всё же, это лишняя работа, некоторая дополнительная путаница... То есть "овчинка не стоит выделки", я так думаю. Я могу описать ситуации, когда подобное будет удобнее своей наглядностью...
Понимаю. Ну вот ты, здравый человек, когда тебе напишут this->IsValid ты какую из объявленных статических функций вызовешь?Я буду считать, что вызывают нестатическую функцию и очень удивлюсь, если она окажется статической. После чего я отфакторю всё дерево классов, связанных с этой бредятиной и сделаю cvs commit.
Чувак говорит о том, что когда у нас уже ЕСТЬ объект, можно засунуть ему в vmt указатели на статические методы тоже. И обрабатывать вызовы с использованием полиморфизма, а потом просто не передавать указатель на объект.спасибо. хоть кто-то меня понял
если я пишу virtual static, наверное, я этого хочу!кстати, написав обход я именно это и сделал, только функций две
Да, это можно сделать.не доказано.
Но код в результате превратится в спагетти.

если я пишу virtual static...то всё ещё не понимаю, что такое virtual и что такое static.

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

спасибо всем за обсуждение! считаю тему закрытой...
открывается конкурс на лучшее обходное решение

> открывается конкурс на лучшее обходное решение
Завести в качестве public-переменной указатель на функцию, который присваивать - в конструкторе... Хотя традиционный подход (правда для несколько иных ситуаций, чем ты описываешь - это уже ближе к моему примеру) - просто завести виртуальную функцию, которая будет возвращать указатель на функцию. Типа свой маленький COM.
Завести в качестве public-переменной указатель на функцию, который присваивать - в конструкторе... Хотя традиционный подход (правда для несколько иных ситуаций, чем ты описываешь - это уже ближе к моему примеру) - просто завести виртуальную функцию, которая будет возвращать указатель на функцию. Типа свой маленький COM.
Эх, всё уже сказано до нас... до меня, то есть.
Остаётся подвести итог. Есть три случая:
1. Во время выполнения тебе нужно точно знать класс объекта (чтобы вызвать именно его метод) - используешь virtual
2а. Во время выполнения тебе не нужно точно знать класс объекта. Метод базового класса тебя вполне устраивает - не пишешь ни virtual, ни static. Даже самые оголтелые сторонники ООП (и Java, в частности) не могут обходиться без этого случая. Хотя бы чтобы вызвать нужный конструктор.
2б. Во время выполнения тебе вааще не нужен объект - используешь static.
Для выбора одного из этих трёх (непересекающихся, заметь) вариантов машине нужно как минимум 2 бита. Однако 2 бита могут быть в четырёх состояниях, и уж прости, что это четвёртое, о котором ты говоришь, запрещено. Так вышло.
В Java с указателями на функции никаких проблем. В твоём случае это может выглядеть например так:
Остаётся подвести итог. Есть три случая:
1. Во время выполнения тебе нужно точно знать класс объекта (чтобы вызвать именно его метод) - используешь virtual
2а. Во время выполнения тебе не нужно точно знать класс объекта. Метод базового класса тебя вполне устраивает - не пишешь ни virtual, ни static. Даже самые оголтелые сторонники ООП (и Java, в частности) не могут обходиться без этого случая. Хотя бы чтобы вызвать нужный конструктор.
2б. Во время выполнения тебе вааще не нужен объект - используешь static.
Для выбора одного из этих трёх (непересекающихся, заметь) вариантов машине нужно как минимум 2 бита. Однако 2 бита могут быть в четырёх состояниях, и уж прости, что это четвёртое, о котором ты говоришь, запрещено. Так вышло.
В Java с указателями на функции никаких проблем. В твоём случае это может выглядеть например так:
public interface Integrable {
public double function(double arg);
}
public class MyMegaIntegrator {
public double integrate(Integrable integrable) {
...
y = integrable.function(x);
....
}
}
public class Test {
public static double megaFunction(double arg) {
...
}
public static void main(String[] args) {
MyMegaIntegrator integrator = new MyMegaIntegrator;
double integral = integrator.integrate(new Integrable {
public double function(double arg) {
return megaFunction(arg);
}
});
}
}
увы, пришлось сделать именно такписать функцию Init вместо конструктора -- вот это негармонично. А все эти твои static virtual...
но это не гармонично
PS. Я фигею, 100 постов на такую тему!..
Завести в качестве public-переменной указатель на функцию, который присваивать - в конструкторе... Хотя традиционный подход (правда для несколько иных ситуаций, чем ты описываешь - это уже ближе к моему примеру) - просто завести виртуальную функцию, которая будет возвращать указатель на функцию. Типа свой маленький COM.можно и так
в любом случае нужно заботиться о лишнем при описании дочернего класса, явно указывать - "ты, пожалуйста, используй эту статическую функцию, чтобы выполнялся полиморфизм при вызове от объекта" - как ни оберни это

я так до сих пор и не понял, почему мне нужно извращаться в моем случае, дублировать функцию или использовать указатель на функцию (что почти одно и то же)
ведь противоречий не возникает при использовании virtual+static. запретили бы тогда вызывать от объекта - и дело с концом... зачем нужна запись obj->static_function при отсутствии virtual-static функций не понятно...

писать функцию Init вместо конструктора -- вот это негармонично.естественно у меня в реальном примере не init...
назови ее xxx, так понятнее? вижу, ты не умеешь концентрироваться на проблеме
Для выбора одного из этих трёх (непересекающихся, заметь) вариантов машине нужно как минимум 2 бита. Однако 2 бита могут быть в четырёх состояниях, и уж прости, что это четвёртое, о котором ты говоришь, запрещено. Так вышло.хорошее сравнение про биты, именно так себе и представляю
цель треда была - выяснить, почему так вышло и связано это или нет с конкретными реализациями компиляторов
ОК.
Ещё напрашивается аналогия с far/near, cdecl/pascal, auto/static, signed/unsigned и т. д.
Представляешь, как было бы удобно - скажем, переменная создаётся в стеке (auto но помнит (static) своё значение...
А всего-то надо было бы написать:
Ещё напрашивается аналогия с far/near, cdecl/pascal, auto/static, signed/unsigned и т. д.
Представляешь, как было бы удобно - скажем, переменная создаётся в стеке (auto но помнит (static) своё значение...

А всего-то надо было бы написать:
auto static int i;
в C++ то, что ты хочешь - делается так:
в Java/C#:
template<class TType>
class A
{
public:
virtual void IsValid(int data)
{
T::IsValid(data);
}
static void IsValid(int data){}
};
class C1:
public A<C1>
{
public:
static void IsValid(int data)
{
//bla-bla 1
}
};
class C2:
public A<C2>
{
public:
static void IsValid(int data)
{
//bla-bla 2
}
};
в Java/C#:
class A
{
public virtual void IsValid(int data)
{
A::IsValid(data);
}
public static void IsValid(int data){}
}
class C1: A
{
public override void IsValid(int data)
{
C1::IsValid(data);
}
public static void IsValid(int data)
{
//bla-bla 1
}
}
class C2: A
{
public override void IsValid(int data)
{
C2::IsValid(data);
}
public static void IsValid(int data)
{
//bla-bla 2
}
}
wow, мне понравилась идея сделать через шаблон, чтобы не вспоминать
только так нельзя перегружать функции:
но идея ясна
минус только в том, что шаблоны сложнее отлаживать
только так нельзя перегружать функции:
virtual void IsValid(int data)
{
T::IsValid(data);
}
static void IsValid(int data){}
но идея ясна
минус только в том, что шаблоны сложнее отлаживать

ведь противоречий не возникает при использовании virtual+staticЛол! Ты вообще читать умеешь? Тебе же разжевали дальше некуда, почему возникают противоречия.
Лол! Ты вообще читать умеешь? Тебе же разжевали дальше некуда, почему возникают противоречия.удивишься, но умею! мне разжевали определения, которые я и так знал. никто не привел примера, где неясно как использовать virtual static функцию. собственно, мне его и хотелось получить, когда я писал первый пост
Её никак нельзя использовать, потому что vtable - часть объекта, а статические функции с объектами не связаны.
Какие тебе ещё объяснения нужны?
Если бы всё было так, как ты и хотел, то есть статики лежали в каком-то особенном месте vtable, то менялась бы сама семантика статических функций - они бы были связаны с объектами. То есть виртуальную функцию никакими ухищрениями нельзя сделать статической, даже путём изменения стандарта.
Какие тебе ещё объяснения нужны?
Если бы всё было так, как ты и хотел, то есть статики лежали в каком-то особенном месте vtable, то менялась бы сама семантика статических функций - они бы были связаны с объектами. То есть виртуальную функцию никакими ухищрениями нельзя сделать статической, даже путём изменения стандарта.
> никто не привел примера, где неясно как использовать virtual static функцию
пример 1:
пример 2:
пример 3:
Какой из методов, ты хочешь, чтобы в каждом из вариантов был вызван (A.IsValid или B.IsValid)?
class A
{
public virtual static IsValid
{
}
}
class B:A
{
public override static IsValid
{
}
}
пример 1:
A a = new A;
a.IsValid;
пример 2:
B b = new B;
b.IsValid;
пример 3:
B b = new B;
Execute(b);
void Execute(A a)
{
a.IsValid;
}
Какой из методов, ты хочешь, чтобы в каждом из вариантов был вызван (A.IsValid или B.IsValid)?
Её никак нельзя использовать, потому что vtable - часть объекта, а статические функции с объектами не связаны.Перечитай тред, если осилишь... Все эти моменты уже обсудили, и не один раз.
Какие тебе ещё объяснения нужны?
Если бы всё было так, как ты и хотел, то есть статики лежали в каком-то особенном месте vtable, то менялась бы сама семантика статических функций - они бы были связаны с объектами. То есть виртуальную функцию никакими ухищрениями нельзя сделать статической, даже путём изменения стандарта.
Если кратно - отличие статической функции от простой функции-члена (не важно, виртуальная она или нет) - в том, что в обычной функции неявно передаётся указатель на объект. Поэтому простую функцию без объекта вызвать принципиально невозможно. Допустим, у нас есть виртуальная функция член - тогда её проблема состоит только в том, что не понятно, как её найти без таблицы указателей на виртуальные функции, но если знать, где она лежит - то её можно вызвать и без объекта. То есть, это тем не менее - полноценная статическая функция, просто появляются некоторые дополнительные проблемы с нахождением указателя на неё. То есть, подобное вполне реально реализовать, однако проблема, как мне сейчас кажется - что просто было лень заморачиваться подобными нетривиальными конструкциями, которые, при этом, нужны достаточно редко... Тем более, что можно было много других вещей доработать, если бы большое желание было, вместо этого.
По-моему, гражданин просто ж0стко прикалывается. Сколько раз сказано - переопределять статические функции в производных классах никто не запрещает, ты только пальцем покажи, какую именно (какого именно класса) статический метод с этим именем ты хочешь вызвать; если же на этапе компиляции этого сказать нельзя, а надо смотреть, какого конкретно класса данный объект, значит, нужен this (ну, чтобы как-то обозначить этот конкретный объект). А this и static - вещи взаимоисключающие. Чё не понятно-то?
у тебя логическая ошибка
Ошибка ты хотел сказать?
> Чё не понятно-то?
Вот это вот не понятно:
> А this и static - вещи взаимоисключающие.
Что такое static (применительно к Ф-Ч)? В случае, если функция не виртуальная, а обычная Ф-Ч - то этоо такая функция, которая не получает указателя на объект в качестве параметров. Теперь добавляем слово virtual - по определению и смыслу этого слова, для того, чтобы обратиться к функции, необходимо посмотреть на таблицу виртуальных функций соответствующего объекта.
То есть:
Механизм виртуальных функций срабатывает ДО запуска кода функции, его суть, смысл заключается в том, чтобы получить указатель на функцию по объекту - после того, как этот указатель найден, виртуальную функцию нельзя отличить от обычной, они на следующем этапе будут ИДЕНТИЧНЫМИ.
Механизм статических функций срабатывает во время запуска функции (при передачи параметров в стек и по ходу всего исполнения функции, так как компилятор внутри функции не имеет указателя на объект.
Таким образом, слова virtual и static - не противоречат друг другу! Да, virtual накладывает некоторые ограничения и вносит дополнительную путаницу - но явных противоречий здесь нет! Это не антонимы, это просто разные механизмы разного назначения.
Вот это вот не понятно:
> А this и static - вещи взаимоисключающие.
Что такое static (применительно к Ф-Ч)? В случае, если функция не виртуальная, а обычная Ф-Ч - то этоо такая функция, которая не получает указателя на объект в качестве параметров. Теперь добавляем слово virtual - по определению и смыслу этого слова, для того, чтобы обратиться к функции, необходимо посмотреть на таблицу виртуальных функций соответствующего объекта.
То есть:
Механизм виртуальных функций срабатывает ДО запуска кода функции, его суть, смысл заключается в том, чтобы получить указатель на функцию по объекту - после того, как этот указатель найден, виртуальную функцию нельзя отличить от обычной, они на следующем этапе будут ИДЕНТИЧНЫМИ.
Механизм статических функций срабатывает во время запуска функции (при передачи параметров в стек и по ходу всего исполнения функции, так как компилятор внутри функции не имеет указателя на объект.
Таким образом, слова virtual и static - не противоречат друг другу! Да, virtual накладывает некоторые ограничения и вносит дополнительную путаницу - но явных противоречий здесь нет! Это не антонимы, это просто разные механизмы разного назначения.
Или если тебе нужно контролировать процесс создания классов: можно объявить конструктор протектедом, и позволять создавать класс только через вызов статической функции.
а как запрещать создание не через конструктор? в java и с++
// Механизм виртуальных функций срабатывает ДО запуска кода функции, его суть, смысл заключается в том, чтобы получить указатель на функцию по __объекту__ - после того,
По объекту, но не по this? Как это?
Видишь ли перед вызовом метода указатель на данный объект можно
- либо поместить в стек
- либо не помещать в стек
Если функция static, она указатель в стек не помещает. Если нет - помещает, даже самая что ни на есть virtual. Как совместить эти два действия, я не понимаю.
По объекту, но не по this? Как это?
Видишь ли перед вызовом метода указатель на данный объект можно
- либо поместить в стек
- либо не помещать в стек
Если функция static, она указатель в стек не помещает. Если нет - помещает, даже самая что ни на есть virtual. Как совместить эти два действия, я не понимаю.
> По объекту, но не по this? Как это?
> Если функция static, она указатель в стек не помещает. Если нет - помещает, даже самая что ни на есть virtual.
> Как совместить эти два действия, я не понимаю
А в чем проблема?
Вот, допустим есть код вида
После создания объект представляет из себя кусок с двумя переменными - переменной var1, и переменной v_ptr (где хранится сама таблица виртуальных функций - не помню, вроде она одна на весь класс, а не на кажный объект, но могу ошибаться, и это не принципиально). Далее, мы хотим вызвать aa.func1(10). При этом КОМПИЛЯТОР делает следующее:
считывает неявную переменную aa.v_ptr, после чего подставляет call-вызов функции aa.v_ptr[0], запихнув в стек дополнительно 2 переменные - переменную this, и переменную x. Ну, обычный вызов обычной статической функции. Теперь, допустим, мы должны вызвать условную статическую виртуальную функцию. Что должен делать КОМПИЛЯТОР - считать неявную переменную aa.v_ptr (как и раньше подставить call - вызов функции aa.v_ptr[1], но при этом в стек запихивать this ему не нужно! Да, чтобы вызвать функцию - указатель на созданный объект нужен, но только потому, что иначе нельзя установить, где лежит указатель на функцию. После того, как указатель получен - знать об объекте ничего не нужно.
> Если функция static, она указатель в стек не помещает. Если нет - помещает, даже самая что ни на есть virtual.
> Как совместить эти два действия, я не понимаю
А в чем проблема?
Вот, допустим есть код вида
class m_class{ public:
int var1;
m_class
{var1=13666;}
virtual int func1(int x)
{ printf("%d",x); }
virtual static int func2(int x)
{ printf("%d",x); }
};
///////
m_class aa;
После создания объект представляет из себя кусок с двумя переменными - переменной var1, и переменной v_ptr (где хранится сама таблица виртуальных функций - не помню, вроде она одна на весь класс, а не на кажный объект, но могу ошибаться, и это не принципиально). Далее, мы хотим вызвать aa.func1(10). При этом КОМПИЛЯТОР делает следующее:
считывает неявную переменную aa.v_ptr, после чего подставляет call-вызов функции aa.v_ptr[0], запихнув в стек дополнительно 2 переменные - переменную this, и переменную x. Ну, обычный вызов обычной статической функции. Теперь, допустим, мы должны вызвать условную статическую виртуальную функцию. Что должен делать КОМПИЛЯТОР - считать неявную переменную aa.v_ptr (как и раньше подставить call - вызов функции aa.v_ptr[1], но при этом в стек запихивать this ему не нужно! Да, чтобы вызвать функцию - указатель на созданный объект нужен, но только потому, что иначе нельзя установить, где лежит указатель на функцию. После того, как указатель получен - знать об объекте ничего не нужно.
ОК. Убедил.
1 - A
Какой из методов, ты хочешь, чтобы в каждом из вариантов был вызван (A.IsValid или B.IsValid)?
2 - B
3 - B
в общем, как при полиморфизме
идея такова для virtual static (раз разрешили зачем-то использовать запись obj->stat_func)
если используется класс::функция - то понятно какой код исполнять еще на этапе компиляции
если написано объект->функция, то, все-таки, хотелось бы видеть полиморфные свойства
как такую идею реализовать - хорошо написал
на данный момент запись obj->stat_func только вводит в заблуждение и может привести к ошибкам
подозреваю, что virtual static запретили, чтобы тем, кто привык, что про статику все известно на этапе компиляции, было удобнее
вообще, имхо, статик для метода класса должен означать лишь то, что данные объекта не используется, даже если он участвует в вызове - в общем-то у Бьерна именно так и написано
никто не привел примера, где неясно как использовать virtual static функциюЛогично что из одной static virtual функции может вызываться другая static virtual функция? И она должна вызывать "правильная", так ведь? Поэтому не передавать указатель на объект нельзя, а значит можно без ущерба с точки зрения оптимизации слово static стереть.
Логично что из одной static virtual функции может вызываться другая static virtual функция? И она должна вызывать "правильная", так ведь? Поэтому не передавать указатель на объект нельзя, а значит можно без ущерба с точки зрения оптимизации слово static стереть.Нет, логичным было бы, что в силу этого из такой виртуальной статической функции нельзя было бы вызвать другую виртуальную функцию (в том числе статическую). Да, дополнительное ограничение, но не принципиальное... То есть понятно, что из-за подобных ограничений полезность подобных функций уменьшается, но это не значит, что они совсем уж бесполезны... Просто нерациональны.
Нет, логичным было бы, что в силу этого из такой виртуальной статической функции нельзя было бы вызвать другую виртуальную функцию (в том числе статическую). Да, дополнительное ограничение, но не принципиальное... То есть понятно, что из-за подобных ограничений полезность подобных функций уменьшается, но это не значит, что они совсем уж бесполезны... Просто нерациональны.достаточно использовать для вызова вирчуал-статик методов только 2 записи: класс::функция, объект->функция, а остальные считать ошибочными.
т.к. в статической функции нельзя использовать this, привязка к объекту нам не нужна внутри такой функции и все вызовы в-с функций внутри будут однозначно определены
в этом случае полезность остается прежней

Перечитай тред, если осилишь... Все эти моменты уже обсудили, и не один раз.Чуве, я в курсе, что такое статик и как оно работает. Отвечать, не прочитав всего треда, тоже не имею привычки. Поэтому не надо рассказывать мне вкратце, что было раньше. Я это и сам сделал своим постом.
где хранится сама таблица виртуальных функций - не помню, вроде она одна на весь класс, а не на кажный объект, но могу ошибаться, и это не принципиальноТы ошибаешься, она на каждый объект, и это принципиально. То есть доступа к виртуальной функции нельзя получить без объекта. Запись вида имя_класса::имя_виртуальной_статической_функции не имеет смысла. Или ты предлагаешь ещё и имена статических функций хранить в двух местах?
> Ты ошибаешься, она на каждый объект, и это принципиально.
То есть, приплюснутые насильники нагло лгут,
когда говорят про сильную типизацию.
---
...Я работаю антинаучным аферистом...
То есть, приплюснутые насильники нагло лгут,
когда говорят про сильную типизацию.
---
...Я работаю антинаучным аферистом...
> Ты ошибаешься, она на каждый объект, и это принципиально.
Неправда. Таблица общая на все объекты класса. В самих объектах хранится только указатель на неё.
> Запись вида имя_класса::имя_виртуальной_статической_функции не имеет смысла.
Неправда. Компилятору известны адреса функций, больше здесь ничего не требуется.
Неправда. Таблица общая на все объекты класса. В самих объектах хранится только указатель на неё.
> Запись вида имя_класса::имя_виртуальной_статической_функции не имеет смысла.
Неправда. Компилятору известны адреса функций, больше здесь ничего не требуется.
"В ваш дурдом уже провели интернет?"
Почему насильники? Куда делись боевики? На другую траву перешёл? Или сменил психиатра?
Почему насильники? Куда делись боевики? На другую траву перешёл? Или сменил психиатра?
Боевиков нету, есть насильники и сантехники.
---
...Я работаю антинаучным аферистом...
---
...Я работаю антинаучным аферистом...
> Что должен делать КОМПИЛЯТОР - считать неявную переменную aa.v_ptr (как и раньше подставить call - вызов функции aa.v_ptr[1], но при этом в стек запихивать this ему не нужно!
Тогда получится, что из такого метода - мы не сможем вызывать другие виртуальные методы, в том числе - даже virtual static, т.е. решение получается незамкнутое.
Тогда получится, что из такого метода - мы не сможем вызывать другие виртуальные методы, в том числе - даже virtual static, т.е. решение получается незамкнутое.
мы не сможем вызывать другие виртуальные методы, в том числе - даже virtual staticЯ им уже говорил. , что в этом их "исчислении" логично будет запретить вызывать из static (даже virtual) что-то зависящее от объекта, в частности, virtual (даже static). Вот такой замкнутый круг хехе

Это всё абстрактные рассуждения, которые без привязки к конкретным задачам бесполезны.
Что мешает вызвать virtual static метод? Отсутствие объекта не проблема, если известен нужный класс (типичный случай - вызов метода предка). Если же класс не известен и никакого объекта нет, то проблема не в методе, а в постановке задачи, где требуется такой вызов непонятно зачем совершить.
Что мешает вызвать virtual static метод? Отсутствие объекта не проблема, если известен нужный класс (типичный случай - вызов метода предка). Если же класс не известен и никакого объекта нет, то проблема не в методе, а в постановке задачи, где требуется такой вызов непонятно зачем совершить.
> что-то зависящее от объекта, в частности, virtual (даже static).
Ошибочка вышла: virtual static зависит не от объекта, а только от его типа. Разница принципиальная.
Ошибочка вышла: virtual static зависит не от объекта, а только от его типа. Разница принципиальная.
// Это всё абстрактные рассуждения, которые без привязки к конкретным задачам бесполезны.
Ну придумай сам конкретную задачу. Например, затасканную иерархию форм. Пусть статическая виртуальная функция пишет: "Я прямоугольник" или "Я круг".
// Что мешает вызвать virtual static метод? Отсутствие объекта не проблема, если известен нужный класс
Если известен (при компиляции) нужный класс, то мы пишем:
Ну придумай сам конкретную задачу. Например, затасканную иерархию форм. Пусть статическая виртуальная функция пишет: "Я прямоугольник" или "Я круг".
// Что мешает вызвать virtual static метод? Отсутствие объекта не проблема, если известен нужный класс
Если известен (при компиляции) нужный класс, то мы пишем:
НужныйКласс::нужныйМетод(...);. Если не изветен, то нужен this, причем именно this, а не какое-то производное знание вроде названия класса, так как мы тут же захотим вызывать другие виртуальные статические методы.
> Если не изветен, то нужен this, причем именно this, а не какое-то производное знание вроде названия класса, так как мы тут же захотим вызывать другие виртуальные статические методы.
Не надо причину со следствием путать.
Правильный подход выглядит так: сначала ставится задача, потом определяются средства решения. Здесь почему-то упорно предлагается всё вывернуть наизнанку: сначала берётся метод, а потом под него подгоняется какая-то неудобная задача, причём даже не задача, а нечто с шапкозакидательской аргументацией ("так как мы тут же захотим ...").
Просто статические методы широко используются без всяких this, и это не является проблемой. virtual static отличается лишь в одном: его можно вызывать не только напрямую, но и через чью-нибудь VMT.
Мне сложно представить задачу, где понадобился бы virtual static, разве что какая-нибудь отладка или низкоуровневые извраты, но это совсем не значит, что такой механизм не имеет права на существование. Да, его возможности ограничены, но не более того.
Не надо причину со следствием путать.
Правильный подход выглядит так: сначала ставится задача, потом определяются средства решения. Здесь почему-то упорно предлагается всё вывернуть наизнанку: сначала берётся метод, а потом под него подгоняется какая-то неудобная задача, причём даже не задача, а нечто с шапкозакидательской аргументацией ("так как мы тут же захотим ...").
Просто статические методы широко используются без всяких this, и это не является проблемой. virtual static отличается лишь в одном: его можно вызывать не только напрямую, но и через чью-нибудь VMT.
Мне сложно представить задачу, где понадобился бы virtual static, разве что какая-нибудь отладка или низкоуровневые извраты, но это совсем не значит, что такой механизм не имеет права на существование. Да, его возможности ограничены, но не более того.
> Правильный подход выглядит так: сначала ставится задача, потом определяются средства решения.
В жизни используется много правильных подходов.
Это правильный - инженерный подход, когда сначала определяется что мы хотим решить, а потом - как.
Есть еще правильный - научный/теоретический подход, когда изучаются и определяются средства, а уже потом ищутся задачи, для решения которых мы эти средства можем использовать.
В жизни используется много правильных подходов.
Это правильный - инженерный подход, когда сначала определяется что мы хотим решить, а потом - как.
Есть еще правильный - научный/теоретический подход, когда изучаются и определяются средства, а уже потом ищутся задачи, для решения которых мы эти средства можем использовать.
> научный/теоретический подход, когда изучаются
> и определяются средства, а уже потом ищутся задачи
Сразу видно математика.
---
"Унивеpситет pазвивает все способности, в том числе глупость."
А. Чехов
> и определяются средства, а уже потом ищутся задачи
Сразу видно математика.
---
"Унивеpситет pазвивает все способности, в том числе глупость."
А. Чехов
Кстати, в стандарте, раздел 10.3, пункт 7 как раз говорится о том, почему нельзя употреблять vitrual static.
> Ты ошибаешься, она на каждый объект, и это принципиально.Ладно, сойдёмся на том, что в стандарте это не оговорено, и реализовано может быть и тем и другим способами.
Неправда. Таблица общая на все объекты класса. В самих объектах хранится только указатель на неё.
> в стандарте, раздел 10.3, пункт 7 как раз говорится о том, почему нельзя употреблять vitrual static
Стандарт приводит тоже самое рассуждение: если без объекта нельзя сделать вызов, то функция не может быть статической. С технической точки зрения утверждение неверно, что здесь уже подробно расписали. С точки зрения ООП - другой вопрос, наверное, есть какие-то грабли.
Поиск в гугле даёт ссылки на различные обсуждения данного вопроса, но разгребать всё это пока желания нет.
Стандарт приводит тоже самое рассуждение: если без объекта нельзя сделать вызов, то функция не может быть статической. С технической точки зрения утверждение неверно, что здесь уже подробно расписали. С точки зрения ООП - другой вопрос, наверное, есть какие-то грабли.
Поиск в гугле даёт ссылки на различные обсуждения данного вопроса, но разгребать всё это пока желания нет.
бля, понаписали тут, а на мой вопрос не ответили, как запретить не через конструктор экземпляр создавать? в c++ и java
Это, видимо, еще более жесткий каламбур?
вот к примеру у меня есть суперкласс C и дохрена потомков всяких, я создаю экземпляр с помощью конструктора:
C myObj = C::construct(myParm);
а внутри construct в зависимости от параметра создается экземпляр одного из потомков, ну и еще что-нибудь делается типа инициализации
как мне запретить вызов new для потомка не из конструктора?
C myObj = C::construct(myParm);
а внутри construct в зависимости от параметра создается экземпляр одного из потомков, ну и еще что-нибудь делается типа инициализации
как мне запретить вызов new для потомка не из конструктора?
Вчера ночью точно так же, как и ты, написал на С++. Приводить не стал по одной причине: для передачи указателя на класс куда-либо, придётся делать ещё один базовый класс для "template<class TType>class A". Что в общем-то выглядит менее красиво, чем виртуальная функция, вызывающая статическую.
Объявить конструкторы потомков protected/private, сделать базовый класс friend'ом.
это в C++? а в java как?
Объявить у дочерних классов конструкторы с доступом в пределах пакета.
А что поконкретнее ты хочешь? Вроде сделал свой класс final, и все свободны. Или не сделал final. Но тогда у тебя ещё 2 опции: public class или /* package */ class, как уже сказал .
// ...если без объекта нельзя сделать вызов, то функция не может быть статической. С технической точки зрения утверждение неверно, что здесь уже подробно расписали.
По-моему, один из нас идиот. Вроде все согласились, что можно не помещать в (или, скорее выталкивать из, для тех у кого есть только стек; ну как в Форте) стек this специально для virtual static метода. Но совсем без this не обойтись. А раз так, зачем делать вид, что его нет?
Когда ты это поймёшь?
По-моему, один из нас идиот. Вроде все согласились, что можно не помещать в (или, скорее выталкивать из, для тех у кого есть только стек; ну как в Форте) стек this специально для virtual static метода. Но совсем без this не обойтись. А раз так, зачем делать вид, что его нет?
Когда ты это поймёшь?
> По-моему, один из нас идиот.
Самокритично.
> Вроде все согласились, что можно не помещать в (или, скорее выталкивать из, для тех у кого есть только стек; ну как в Форте) стек this специально для virtual static метода.
Cогласились, я разве с этим спорю?
> Но совсем без this не обойтись.
Очень даже обойтись. virtual static можно использовать, как обычный static, что указывалось в этом треде очень много раз.
> А раз так, зачем делать вид, что его нет?
Не так.
> Когда ты это поймёшь?
В своей башке сначала порядок наведи.
Самокритично.
> Вроде все согласились, что можно не помещать в (или, скорее выталкивать из, для тех у кого есть только стек; ну как в Форте) стек this специально для virtual static метода.
Cогласились, я разве с этим спорю?
> Но совсем без this не обойтись.
Очень даже обойтись. virtual static можно использовать, как обычный static, что указывалось в этом треде очень много раз.
> А раз так, зачем делать вид, что его нет?
Не так.
> Когда ты это поймёшь?
В своей башке сначала порядок наведи.
Чем отличается
имя_класса::имя_виртуальной_статической_функции(...)от имя_класса::имя_статической_функции(...) ?
Ничем.
А зачем тогда слово "virtual"?
Чтобы при вызове вида obj->static_virtual_method метод выбирался в зависимости от типа объекта, на который указывает obj в процессе выполнения кода.
obj->static_virtual_methodКак ты думаешь, что значит, "obj->" для процессора? Т.е., какими инструкциями ты бы это представил на ассемблере? Хоть на каком-нибудь: Intel, MSIL, JVM...
А как ты думаешь, что значит, "const int" для процессора?
---
...Я работаю антинаучным аферистом...
---
...Я работаю антинаучным аферистом...
Само по себе ничего не значит. А вот для компилятора значит. В случае просто static метода, его адрес будет определён сразу по типу указателя и сгенерирован прямой вызов. От virtual static ожидается вызов через таблицу виртуальных методов объекта.
> obj->static_virtual_method
> Как ты думаешь, что значит, "obj->" для процессора?
Имеется в виду, что если присутствует такая запись, со ссылкой на объект - то значит сам объект существует, и из него можно извлечь указатель на таблицу виртуальных функций (тем же образом, как и извлекается указатель для обычных виртуальных функций). Если же конкретного объекта нет (например, хочется вызвать одну статическую функцию из другой то вызов можно производить лишь по записи вида class_name::static_virtual_method.
> Как ты думаешь, что значит, "obj->" для процессора?
Имеется в виду, что если присутствует такая запись, со ссылкой на объект - то значит сам объект существует, и из него можно извлечь указатель на таблицу виртуальных функций (тем же образом, как и извлекается указатель для обычных виртуальных функций). Если же конкретного объекта нет (например, хочется вызвать одну статическую функцию из другой то вызов можно производить лишь по записи вида class_name::static_virtual_method.
// От virtual static ожидается вызов через таблицу виртуальных методов объекта.
Минуя this?
Минуя this?
> Т.е., какими инструкциями ты бы это представил на ассемблере? Хоть на каком-нибудь: Intel, MSIL, JVM...
вот так (псевдокод):
объявления:
вызовы:
вот так (псевдокод):
объявления:
class objtype;
objtype* obj;
вызовы:
; obj->method;
push obj
call objtype::method
; obj->static_method;
call objtype::static_method
; obj->virtual_method;
mov r0, [obj+vmt_offset] ; адрес VMT
mov r1, [r0+virtual_method_index] ; адрес метода
push obj
call r1
; obj->virtual_static_method;
mov r0, [obj+vmt_offset]
mov r1, [r0+virtual_static_method_index]
call r1
OK, спасибо.
А этот вот obj, который мелькает в ассемблерном коде, это часом не this, без которого, по твоим словам, можно обойтись?
А этот вот obj, который мелькает в ассемблерном коде, это часом не this, без которого, по твоим словам, можно обойтись?
Для кого-то он, безусловно, this, в частности, для самого obj. Для куска кода, в котором делаются эти вызовы - совсем не обязательно.
Так ты под конструктором метод с именем construct понимаешь? Оригинально.
Конструктор (в терминологии C++) имеет те же модификаторы доступа, что и остальные методы, так что вопрос удивителен. Ответ, впрочем, дали.
Конструктор (в терминологии C++) имеет те же модификаторы доступа, что и остальные методы, так что вопрос удивителен. Ответ, впрочем, дали.
ОК, спасибо, ясно.
а я с c++ не дружу
что там есть уонструктор?
что там есть уонструктор?Статические методы и переменные класса отличаются от обычных тем, что статические методы не принимают указатель на объект (экземпляр) класса в качестве первого (неявного) аргумента, а статические переменные не находятся в памяти объекта класса.
Виртуальные методы отличаются тем, что вызываются в соответствии с настоящим классом объекта, даже если обращение происходит через указатель на предка класса объекта. Для этого каждый объект с виртуальными методами содержит в качестве данных таблицу виртуальных методов и вызов происходит через эту таблицу (из таблицы берётся указатель на метод и делается косвенный вызов).
Таким образом, для того, чтобы метод был виртуальным, нужно чтобы указатель на этот метод был в любом объекте класса (внутри таблицы виртуальных функций). Статические функции не имеют доступа к объекту (так как не получают указатель на него в качестве аргумента а значит, не имеют доступа к таблице виртуальных методов, значит не могут быть виртуальными. Более того, обращение к статическим методам и переменным возможно и в случае отсутствия вообще объектов класса.
В принципе, можно сделать, чтобы статические методы были виртуальными, но это на мой взгляд не имеет практического смысла.
Виртуальные методы отличаются тем, что вызываются в соответствии с настоящим классом объекта, даже если обращение происходит через указатель на предка класса объекта. Для этого каждый объект с виртуальными методами содержит в качестве данных таблицу виртуальных методов и вызов происходит через эту таблицу (из таблицы берётся указатель на метод и делается косвенный вызов).
Таким образом, для того, чтобы метод был виртуальным, нужно чтобы указатель на этот метод был в любом объекте класса (внутри таблицы виртуальных функций). Статические функции не имеют доступа к объекту (так как не получают указатель на него в качестве аргумента а значит, не имеют доступа к таблице виртуальных методов, значит не могут быть виртуальными. Более того, обращение к статическим методам и переменным возможно и в случае отсутствия вообще объектов класса.
В принципе, можно сделать, чтобы статические методы были виртуальными, но это на мой взгляд не имеет практического смысла.
Ты бы перед своим постом написал "всё предыдущее ниасилил, многа букф".

> статические методы не принимают указатель на объект
> даже если обращение происходит через указатель
> каждый объект [...] содержит в качестве данных таблицу виртуальных методов
> из таблицы берётся указатель
Ладно, это всё детали реализации, а семантически это как?
---
...Я работаю антинаучным аферистом...
> даже если обращение происходит через указатель
> каждый объект [...] содержит в качестве данных таблицу виртуальных методов
> из таблицы берётся указатель
Ладно, это всё детали реализации, а семантически это как?
---
...Я работаю антинаучным аферистом...
Java:
class A {
public static void f {
System.out.println("From A!");
}
}
class B extends A {
public static void f {
System.out.println("From B!");
}
}
public class Simple extends B {
public static void main(String[] args) throws Exception {
A a = new Simple;
a.getClass.getMethod("f", new Class[0]).invoke(null, new Object[0]);
}
}На C++ с включённым RTTI должно быть что-то похожее.Семантически выражение «virtual static» противоречиво.
Теперь скажи, это выполнится быстрее виртуальных функций, которые вызывают статические? Или, может быть, это более читаемо/лаконично? На последний вопрос ответ точно отрицательный, т.к. все джава среды очень хорошо позволяют прыгать по методам.
На С++ подобное решение будет гораздо тяжелее.
На С++ подобное решение будет гораздо тяжелее.
Java. Мы не торопимся.
Проблемы людей, которые хотят сэкономить на push obj, продолжая копаться в таблице виртуальных функций, мне вообще не понять. Это был чисто теоретический изыск.
Проблемы людей, которые хотят сэкономить на push obj, продолжая копаться в таблице виртуальных функций, мне вообще не понять. Это был чисто теоретический изыск.
Java. Мы не торопимся.А вот это очень и очень зря. Потому что из-за тонн тормозного Джава кода этот язык считают тормозным и убогим.
Это была шутка.
---
"I will use smilies every time I am joking. I will use smilies.."
---
"I will use smilies every time I am joking. I will use smilies.."
В Delphi есть "virtual static" функции - это называется virtual class function. Используются они не часто. Основной их смысл в том, что этим функциям вместо указателя на объект передается указатель на таблицу виртуальных методов (в частности из них можно вызывать другие class function и конструкторы, а обычные методы вызывать, разумеется, нельзя). В С++ их нет, потому что язык развивался по-другому и теперь уже сложно что-либо изменить.
Оставить комментарий
a10063
имеется ввиду вопрос не про конкретную реализацию компиляторов сегодня, а какие причины побудили это запретить (если не ошибаюсь, в стандарте)есть ли какой-то пример, где virtual и static конфликтуют?