Тут размещают свои топики новички в С/С++.

Тема в разделе "LANGS.C", создана пользователем nitrotoluol, 4 мар 2007.

  1. KeSqueer

    KeSqueer Сергей

    Публикаций:
    0
    Регистрация:
    19 июл 2007
    Сообщения:
    1.183
    Адрес:
    Москва
    Вопрос по C#.
    Можно ли каким-нибудь не unsafe способом сделать следующее:

    struct Vertex
    {
    Vertex Parent;
    }
    ?
    Т.е. структура содержит указатель на другую такую же структуру.

    Если использовать class вместо struct, то проблемы нет, а так - типа зацикливание. Если ставить Vertex *Parent;, то пишет unsafe.
    Извиняюсь за тупой вопрос)
    ps
    короче, не могу скомпилировать вот это (опция /unsafe включена):
    Код (Text):
    1. using System;
    2.  
    3. namespace Topl
    4. {
    5.  
    6.     public struct Vertex
    7.     {
    8.         public uint Id;
    9.         public unsafe Vertex* Parent;
    10.         public DynamicArray InEdges;
    11.         public DynamicArray OutEdges;
    12.     }
    13.  
    14.     public struct Edge
    15.     {
    16.         public uint Weight;
    17.         public unsafe Vertex* ToVertex;
    18.         public unsafe Vertex* FromVertex;
    19.     }
    20.  
    21.     public struct DynamicArray
    22.     {
    23.         private unsafe object* Elems;
    24.         private uint Count;
    25.         private uint Capacity;
    26.         public uint GetCount()
    27.         {
    28.             return Count;
    29.         }
    30.         public object this[uint index]
    31.         {
    32.             get
    33.             {
    34.                 return Elems[index];
    35.             }
    36.         }
    37.         public void AddElem(object Elem)
    38.         {
    39.             if (Count >= Capacity)
    40.             {
    41.                 Capacity += 100;
    42.                 object[] NewElems = new object[Capacity];
    43.                 for (uint i = 0; i < Count; i++)
    44.                     NewElems[i] = Elems[i];
    45.                 Elems = NewElems;
    46.             }
    47.             Elems[Count++] = Elem;
    48.         }
    49.         public void RemoveElem(object Elem)
    50.         {
    51.             for (uint i = 0; i < Count; i++)
    52.             {
    53.                 if (Elem.Equals(Elems[i]))
    54.                 {
    55.                     for (uint j = i; j < Count - 1; j++)
    56.                         Elems[j] = Elems[j + 1];
    57.                     Elems[--Count] = default(T);
    58.                 }
    59.             }
    60.         }
    61.         public object Retrieve(uint index)
    62.         {
    63.             return Elems[index];
    64.         }
    65.     }
    66.  
    67.     class Program
    68.     {
    69.         static void Main ()
    70.         {
    71.             Console.ReadKey(true);
    72.         }
    73.     }
    74. }
    Это основы, которые надо бы знать. Буду признателен за помощь.
     
  2. Arthur

    Arthur New Member

    Публикаций:
    0
    Регистрация:
    27 янв 2007
    Сообщения:
    494
    Получение указателя на функцию внутри класса (msvc++)?

    Вот и первые траблы у меня с ООП в msvc++ :dntknw:
    Вот имеется такой код:
    что-то не въезжаю, какой оператор использовать, что бы получить желаемое?
     
  3. varnie

    varnie New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2005
    Сообщения:
    1.785
    Arthur
    Код (Text):
    1. SomeClass(){
    2.    typedef int(SomeClass::*pf)(int, int);
    3.                pf p = &SomeClass::SomeFunc1;
    4.                int res = (this->*p)(1,23);
    5. }
    но непонятно, зачем в конструкторе класса получать указатель на свою же функцию-член и вызывать ее в нем же. или это просто пример без привязки к реальной задаче?:)

    вот информация: link1 или вот
     
  4. Arthur

    Arthur New Member

    Публикаций:
    0
    Регистрация:
    27 янв 2007
    Сообщения:
    494
    varnie
    Задача реальная - немогу засунуть указатель на функцию вида WNDPROC, которая обязательно должна находиться внутри класса.

    теперь выдает ошибку:
     
  5. censored

    censored New Member

    Публикаций:
    0
    Регистрация:
    5 июл 2005
    Сообщения:
    1.615
    Адрес:
    деревня "Анонимные Прокси"
    ключевое слово static
     
  6. Velheart

    Velheart New Member

    Публикаций:
    0
    Регистрация:
    2 июн 2008
    Сообщения:
    526
    Если сделать функцию статической, то все должно быть ОК.
     
  7. Arthur

    Arthur New Member

    Публикаций:
    0
    Регистрация:
    27 янв 2007
    Сообщения:
    494
    Гы, а как теперь с DlgProc, юзать поля объекта? Нужно что бы диалоговая функция могла юзать поля объекта, а то и нафиг я бы... Можно конечно сделать статической и передавать указатель на объект через задницу (гхм... т. е. winapi) но я не хочу тратить машинное время на это.

    Ох как меня достала это типизация!
     
  8. Arthur

    Arthur New Member

    Публикаций:
    0
    Регистрация:
    27 янв 2007
    Сообщения:
    494
    Интересно, а как в MFC это делается(передается WindowProc в классе CWnd)?
     
  9. censored

    censored New Member

    Публикаций:
    0
    Регистрация:
    5 июл 2005
    Сообщения:
    1.615
    Адрес:
    деревня "Анонимные Прокси"
    Arthur
    кл. слово SetWindowLong ;)

    отказаться от использования классов?
     
  10. Arthur

    Arthur New Member

    Публикаций:
    0
    Регистрация:
    27 янв 2007
    Сообщения:
    494
    censored
    Не, не - в этом вся и прелесть и мазохизм :)

    Вся беда именно в том что невозможно передать адрес функции в WinAPI или любые другие процедуры - либо говорит что несовместимы типы, а когда пытаешься кастить, то вылетает ошибка 'type cast', которая говорит вроде о природной несовместимости двух типов :dntknw: Все это из-за класса.

    Так же конструкция ввида:
    непомогает. Та же самая ботва, только уже с someProc(когда его передаешь в процедуру) :dntknw:
     
  11. censored

    censored New Member

    Публикаций:
    0
    Регистрация:
    5 июл 2005
    Сообщения:
    1.615
    Адрес:
    деревня "Анонимные Прокси"
    Не понял о чем идет речь, но вообще если почитать книжки по написанию гуи или там срц чужие посмотреть, то можно заметить что используется стандартная схема: создается окно, устанавливается один из аттрибутов окна, далее в WndProc используется этот же самый аттрибут для, например, обращения к методам и членам класса.
    Примерно так:
    Код (Text):
    1. class CWindow {
    2. protected:
    3.   int x;
    4.   HWND hWnd;
    5. public:
    6.   CWindow() {
    7.     hWnd = CreateWindow(...);
    8.     SetWindowLongPtr(hWnd, DWL_USER, this);
    9.   }
    10.   static LRESULT CALLBACK WindowProc(
    11.     HWND hwnd,
    12.     UINT uMsg,
    13.     WPARAM wParam,
    14.     LPARAM lParam)
    15.   {
    16.     CWindow *pThis = static_cast<CWindow *>(GetWindowLongPtr(hwnd, DWL_USER));
    17.     ASSERT(pThis != NULL);
    18.     pThis->x = 0; /* just for test */
    19.   }
    20. }
     
  12. Arthur

    Arthur New Member

    Публикаций:
    0
    Регистрация:
    27 янв 2007
    Сообщения:
    494
    В общем-то говоря о заднице, я имел ввиду [Get|Set]WindowLong :)

    Принципиально большой нагрузки нет на эту процедуру, но все же хотелось как то более чисто :)

    Я смотрел прототип класса CWnd, в MFC, так вот они там как-то через хитро-закрученную жопу сделали, то что я хотел, а именно WindowProc объявлена как виртуальная функция:

    Ну собственно вопрос частично решен, но не так как хотелось, так что если кто-нибудь знает... эх...

    Благодарю за внимание.
     
  13. Sol_Ksacap

    Sol_Ksacap Миша

    Публикаций:
    0
    Регистрация:
    6 мар 2008
    Сообщения:
    623
    Arthur
    Кстати, если очень хочется покастить указатели, но компилятор не даёт - можно использовать union:
    Код (Text):
    1. template <class REZ, class SRC> __forceinline
    2. REZ cast(SRC CastFrom)
    3. {
    4.     union
    5.     {
    6.         REZ rez;
    7.         SRC src;
    8.     };
    9.     src = CastFrom;
    10.     return rez;
    11. }
    12.  
    13.  
    14. Пример:
    15. main()
    16. {
    17.     ...
    18.     DWORD x = cast<DWORD>(&MyClass::MyNonStaticFunction);
    19.     ...
    20. }
    Осторожнее с ногами только.
     
  14. Arthur

    Arthur New Member

    Публикаций:
    0
    Регистрация:
    27 янв 2007
    Сообщения:
    494
    Sol_Ksacap
    О! Спасибо!
     
  15. Ra!N

    Ra!N New Member

    Публикаций:
    0
    Регистрация:
    26 окт 2006
    Сообщения:
    111
    В книге "ООП на С++" (Р.Лафоре) написано, что размер long всегда раен 4 байтам. Но вроде бы в некоторых 64 битных компияляторах он равен 8 (gcc,intel c). Разве нет?
     
  16. Forever

    Forever Виталий

    Публикаций:
    0
    Регистрация:
    12 апр 2008
    Сообщения:
    244
    Есть различные модели данных :
    LP64 : int - 4 байта, long - 8 байт
    ILP64 : int - 8 байт, long - 8 байт
    LLP64 : int - 4 байта, long - 4 байта
    Еще ходят сказки про SILP64 в котором short, int, long - занимают 8 байт.
    Каждая компания придерживается своего. Microsoft - LLP64, копиляторы под *nix обычно используют LP64. Так что "Истина где-то рядом." =)
     
  17. Ra!N

    Ra!N New Member

    Публикаций:
    0
    Регистрация:
    26 окт 2006
    Сообщения:
    111
    Forever
    спасибо,все разъяснил! В "размерозависимых" ситуациях походу выход один - stdint.h
     
  18. varnie

    varnie New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2005
    Сообщения:
    1.785
    укажите, плз, каким образом можно задефайнить, скажем, число, чтобы выбрасывать его как объект исключения, но чтобы было визуально более наглядно?
    Код (Text):
    1. try{
    2.   //...code
    3.  throw 1;
    4. }catch(int){
    5.   //do smth
    6. }
    так ненаглядно имхо. или же создать класс лучше?
    Код (Text):
    1. class Dummy{
    2. public:
    3.   Dummy(){}
    4. };
    5.  
    6. try{
    7.   //...code
    8.   throw Dummy();
    9. }catch(const Dummy &d){
    10.   //do smth
    11. }
    но не будет ли это громоздко в моем контексте? спасибо.
     
  19. Arthur

    Arthur New Member

    Публикаций:
    0
    Регистрация:
    27 янв 2007
    Сообщения:
    494
    Я опять к вам с приветом :)

    Код (Text):
    1. class Q
    2. {
    3.     void Void()
    4.     {
    5.         myVoid();
    6.     }
    7.  
    8.     virtual bool myVoid(){return false;}
    9. };
    10.  
    11. class Z : public Q
    12. {
    13.     virtual bool myVoid(){return true;}
    14. };
    Как теперь сделать так чтобы в Z классе, при вызове Void, вызывался myVoid именно в Z классе, а то вызывается myVoid, который находится в Q классе?
     
  20. censored

    censored New Member

    Публикаций:
    0
    Регистрация:
    5 июл 2005
    Сообщения:
    1.615
    Адрес:
    деревня "Анонимные Прокси"
    Arthur
    Код (Text):
    1. // Curiously recurring template pattern
    2.  
    3. #include <iostream>
    4. #include <memory>
    5.  
    6. class IAbstract {
    7. public:
    8.   virtual ~IAbstract() {;}
    9.   virtual void Foo() = 0;
    10. };
    11.  
    12. template <class T>
    13. class CBase : public IAbstract {
    14. public:
    15.   virtual void Foo() {
    16.     static_cast<T *>(this)->doFoo();
    17.   }
    18. private:
    19.   void doFoo() { std::cout << "CBase::doFoo()" << std::endl; }
    20. };
    21.  
    22. class CDerived1 : public CBase<CDerived1> {
    23. public:
    24.   void doFoo() {
    25.     std::cout << "CDerived1::doFoo()" << std::endl;
    26.   }
    27. };
    28.  
    29. class CDerived2 : public CBase<CDerived2> {};
    30.  
    31. int main() {
    32.   typedef std::auto_ptr<IAbstract> AbstractPtr;
    33.  
    34.   AbstractPtr pd1(new CDerived1());
    35.   AbstractPtr pd2(new CDerived2());
    36.  
    37.   pd1->Foo();
    38.   pd2->Foo();
    39. }