Read-only property

Read-only property
GO
  • Rejestracja:prawie 17 lat
  • Ostatnio:ponad 10 lat
0

Znacie jakiś trick by zadziałała poniższa konstrukcja?

Kopiuj
obj.pPointerToSmth->someMethod();

ale tak, by nie można było zmodyfikować wskaźnika w taki sposób:

Kopiuj
obj.pPointerToSmth = someAddress;

Nie chcę zwracać wskaźnika za pomocą metody:

Kopiuj
obj.pPointerToSmth()->someMethod();

Oczywiście potrzebuję ten wskaźnik ustawić jeden raz po uruchomieniu programu, po utworzeniu obiektu, na który ma ów wskaźnik wskazywać. Ustawiłbym go sobie jakimś setterem (metodą).

Próbowałem wykorzystać:
http://www.codeproject.com/Articles/118921/C-Properties
ale Visual C++ Express 2010 nie akceptuje kodu properties.h, zwraca:

Kopiuj
properties.h(5): error C2143: syntax error : missing ')' before '='
properties.h(5): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
properties.h(5): error C2014: preprocessor command must start as first nonwhite space

Przykład:

Kopiuj
// ObjectManager to singleton.
#define objManager ObjectManager::GetInstance()
WinMain()
{
    Window pWindow = new Window(...); // Niech Window będzie jakimś oknem windowsowym.
    objManager.SetPtrToWindow(pWindow);

    // Inny kod...

    objManager.pWindow->Show(); // Wyświetlamy okienko.
    objManager.pWindow = NULL; // Próbujemy zmodyfikować wskaźnik. Źle - kompilator powinien nam w tym miejscu uciąć głowę i rzucić rekinom na pożarcie ;-)
}

EDIT: Udało mi się doprowadzić do działania mechanizm z properties.h, ale ten kawałek kodu:

Kopiuj
objManager.pWindow = NULL;

spowoduje wyświetlenie błędu dopiero po uruchomieniu kompilacji. W trakcie edytowania kodu IDE nie podkreśli tego jako błąd - macie pomysł jak rozwiązać również ten problem?

edytowany 4x, ostatnio: Goodrock
HO
Pokaż kod klasy, bo ciężko coś doradzić z takich nic nie mówiących urywków. Jak ma być coś niezmienne to używa się słówka const.
GO
const można użyć w przypadku korzystania z typowych setterów i getterów. Ja natomiast nie chcę zwracać wartości zmiennych za pomocą metody (gettera). W dodatku zwrócona wartość musi być read-only. Kod mojej klasy i tak Ci w niczym nie pomoże bo to pusty, zwyczajny singleton. IDE nie podkreśla tego co opisałem zapewne z powodu użycia tricku jaki znajduje się w properties.h - w poście jest link do artykułu z kodem zawartym w tym pliku + przykłady użycia.
HO
  • Rejestracja:ponad 13 lat
  • Ostatnio:około 11 lat
  • Postów:283
0

Nie znam specyfiki tego co chcesz osiągnąć, bo jesteś bardzo oszczędny ale const jak wspomniałem wystarcza.

Kopiuj
using namespace std;

class Foo
{
public:
    Foo( int _zmienna ) : zmienna( _zmienna )
    {}

    const int zmienna;
};

int main()
{
    Foo t( 8 );
    cout << t.zmienna; // jest ok - jest dostep
    t.zmienna = 3; // kompilator sypie error bo zmienna read-only
    return 0;
}


Jeśli uważasz mój post za wartościowy - daj punkt.
Mój post pomógł Ci rozwiązać problem - zaznacz go. Pozdrawiam
KR
  • Rejestracja:prawie 16 lat
  • Ostatnio:5 miesięcy
  • Postów:2514
0
Kopiuj
class O
{
public:
  void metoda() {}
};
class A
{
private:
  O o;
public:
 O * const wskaznik;
  A(): wskaznik(&o) {}
};
// cos w ten desen. zwroc uwage na const za *

░█░█░█░█░█░█░█░█░█░█░█░
edytowany 2x, ostatnio: krwq
GO
  • Rejestracja:prawie 17 lat
  • Ostatnio:ponad 10 lat
0

Owszem Hostel jest to dobre rozwiązanie i wystarczy, jeśli w założeniu zmiennej będziemy przypisywać wartość tylko jeden raz - w trakcie utworzenia obiektu. Wtedy lista inicjalizacyjna jest "jak znalazł". W sumie na chwilę obecną wystarczy mi to rozwiązanie. Jeśli zajdzie potrzeba modyfikacji zmiennej po utworzeniu obiektu to użyję pewnego tricku, który mi przypomniałeś:

Kopiuj
void Foo::SetZmienna(int newVal)
{
	*((int*)(&zmienna)) = newVal;
}
 
int main()
{
    Foo t( 8 );
    cout << t.zmienna;
    t.SetZmienna(9);
    return 0;
}
edytowany 1x, ostatnio: Goodrock
KR
  • Rejestracja:prawie 16 lat
  • Ostatnio:5 miesięcy
  • Postów:2514
0

mozna zrobic tez tak:

private: O* o;
public: O*& const const_o;
A(): const_o(o) {}

wtedy o moznesz zmieniac a const_o juz nie


░█░█░█░█░█░█░█░█░█░█░█░
GO
public: O*& const const_o; //warning C4227: anachronism used : qualifiers on reference are ignored
KR
sprobuj tak: public: O* const& const_o;
GO
  • Rejestracja:prawie 17 lat
  • Ostatnio:ponad 10 lat
0

W sumie jeszcze jedna rzecz trochę psuje estetykę - jeśli takich zmiennych będzie dużo to konstruktor się rozrośnie o mnóstwo parametrów w liście inicjalizacyjnej.

HO
  • Rejestracja:ponad 13 lat
  • Ostatnio:około 11 lat
  • Postów:283
0

Owszem, tak może być ale trzeba przyznać że dobrą praktyką jest hermetyzacja danych - czyli używanie set() i get(). Publiczne zmienne są często wynikiem złego zaprojektowania. W końcu jeśli zmienna ma być publiczna to można by użyć struktury a nie klasy.


Jeśli uważasz mój post za wartościowy - daj punkt.
Mój post pomógł Ci rozwiązać problem - zaznacz go. Pozdrawiam
Sarrus
To zależy. Hermetyzacja wszystkiego "bo tak" to jest chyba jeszcze gorsze podejście. Chronić należy te pola, których nieumiejętne użycie może spowodować niepoprawne lub nieoczekiwane działanie obiektu tej klasy.
HO
Na mój gust obiekt powinien zwracać wszystko przez metody - nigdy nie wiadomo czy algorytm nam się nie zmieni. Jak się zmieni to wtedy trzeba będzie dopiero kombinować.
KR
  • Rejestracja:prawie 16 lat
  • Ostatnio:5 miesięcy
  • Postów:2514
0

proponuje Ci zaczac uzywac C#, tam tego typu rzeczy sa wbudowane w jezyk


░█░█░█░█░█░█░█░█░█░█░█░
GO
  • Rejestracja:prawie 17 lat
  • Ostatnio:ponad 10 lat
0

Owszem, tak może być ale trzeba przyznać że dobrą praktyką jest hermetyzacja danych - czyli używanie set() i get(). Publiczne zmienne są często wynikiem złego zaprojektowania. W końcu jeśli zmienna ma być publiczna to można by użyć struktury a nie klasy.

Tak, wiem. Ale chciałem móc używać konstrukcji:

Kopiuj
o.pWnd->someMethod();

zamiast:

Kopiuj
o.GetPointerToWnd()->someMethod();

ponieważ mój obiekt to singleton, który będzie używany wewnątrz większości innych obiektów, i taka konstrukcja skraca kod.

proponuje Ci zaczac uzywac C#, tam tego typu rzeczy sa wbudowane w jezyk

Wiem, i chciałbym napisać całość w C#, ale nie mogę bo C# nie obsługuje jednej ważnej funkcji, która jest niezbędna w moim programie, dyskutowałem o tym dzisiaj w tym wątku:
http://4programmers.net/Forum/Newbie/201986-kilka_pytan_odnosnie_c
Jak już tam wspomniałem - na upartego da się to obejść, ale to trochę jak bicie kotka za pomocą młotka. Poza tym jeszcze nie jestem gotów na przepisywanie tego do C# bo nie skończyłem aplikacji, a nie wiem jakie jeszcze napotkam problemy - wciąż muszę wykorzystywać reverse-engineering. Nie chcę mieć potem kolejnego zonka, że czegoś tam się nie da łatwo zrobić w C#.

edytowany 1x, ostatnio: Goodrock
HO
  • Rejestracja:ponad 13 lat
  • Ostatnio:około 11 lat
  • Postów:283
0

Ja nie widzę tego skrócenia zapisu - zamiast metodę nazwać GetPointerToWnd() możesz w singletonie zrobić zmienną _pWnd oraz metodę zwracającą o nazwie pWnd i wtedy dojdzie Ci tylko nawias.


Jeśli uważasz mój post za wartościowy - daj punkt.
Mój post pomógł Ci rozwiązać problem - zaznacz go. Pozdrawiam
GO
No właśnie cały czas chodzi mi o te nawiasy ;-)
HO
To zrób typedef ;) Teraz będziesz szczęśliwy a po 3 miesiącach może być już mniej radości ;)
GO
Tzn. do czego użyć typedef? Bo coś nie mogę skojarzyć - może z powodu godziny :) I czemu za 3 miesiące mniej radości?
HO
Wycofuje się z typedef - nie tędy droga jednak. Poniosła mnie wyobraźnia ;)
Rekman
  • Rejestracja:prawie 13 lat
  • Ostatnio:prawie 10 lat
  • Postów:148
0

Z tego co się orientuję to kompilator Visual C++ obsługuje właściwości. Jest też dostępna darmowa biblioteka stlsoft (http://www.stlsoft.org) udostępniająca właściwości niezależnie od kompilatora.

Azarien
tylko w trybie C++/CLI
adf88
  • Rejestracja:ponad 21 lat
  • Ostatnio:prawie 12 lat
1

Sposób implementacji nie powinien być wymuszony fizyczną objętością kodu. Takie podejście jest złe. Liczy się przede wszystkim prostota kodu i niewielka objętość "logiczna". To ile powierzchni ekranu zajmuje kod jest na prawdę sprawą podrzędną (zwłaszcza w czasach wielkich ekranów i mechanizmów uzupełniania składni). Ja rozumiem jakieś makro jeśli coś musi być wielokrotnie powielane etc., ale tak kombinować o jeden nawias? Niedobrze. Wspomniany mechanizm uzupełniania składni sam go będzie wstawiać.

Samemu nieraz próbuję tak bezsensownie kombinować i trzeba się w porę otrząsnąć i postawić do pionu.
Mam nadzieję, że Cię przekonałem. Sam zauważyłeś, że logicznie najlepiej pasuje tu metoda. Więc takiej użyj. Im mniej WTF'owego kodu tym lepiej ;) .

edytowany 6x, ostatnio: adf88
HO
Popieram w całości.
GO
Ok przekonałeś mnie :)
Azarien
  • Rejestracja:ponad 21 lat
  • Ostatnio:mniej niż minuta
0

Tak, można w C# stworzyć okno o danej nazwie klasy. Jak? CreateWindow().
Całe Windows Forms napisane jest w WinAPI.

Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)