funkcja zwracająca nazwę klasy (const char* vs char*)

0

Jak to najlepiej zrobić i jakie są różnice tych zapisów:

#include <stdio.h>
#include <conio.h>

class A
{
public:
  const char* nazwa1()       { return "Nazwa 1"; }
  char* nazwa2()             { return "Nazwa 2"; } // Line: 8
  char* nazwa3() const       { return "Nazwa 3"; } // Line: 9
  const char* nazwa4() const { return "Nazwa 4"; }
};

int main()
{
  A test;
  printf("%s\n%s\n%s\n%s",test.nazwa1(),test.nazwa2(),test.nazwa3(),test.nazwa4());
  getch();
  return 0;
}

wszystkie wydają mi się podobne i mi się już to trochę miesza.
To mówi kompilator:

In member function 'char* A::nazwa2()':
(Line: 8) warning: deprecated conversion from string constant to 'char*'
In member function 'char* A::nazwa3() const':
(Line: 9) warning: deprecated conversion from string constant to 'char*'
=== Build finished: 0 errors, 2 warnings ===
0

Zapis nr 1 zwraca ci wskaźnik na stały ciąg znaków (tzn nie będziesz miał możliwosci go zmieniać)
Zapis nr 2 zwraca ci wskaźnik na pewien ciąg znaków (teoretycznie mógłbyś go zmieniać, ale to co stoi przy returnie jest STAŁYM napisem, wiec to się nie skompiluje)
Zapis nr 3 robi to samo co zapis nr 1, ale dodatkowo pozwala ci pracować na stałych obiektach klasy, tzn jeśli stworzysz
const A obiekt;
to na tym obiekcie mozesz wywołać jedynie metodę napis3().

0
Shalom napisał(a)

Zapis nr 2 zwraca ci wskaźnik na pewien ciąg znaków (teoretycznie mógłbyś go zmieniać, ale to co stoi przy returnie jest STAŁYM napisem, wiec to się nie skompiluje)
Skompiluje się. Literał napisowy można potraktować jako char*, ale to jest bardzo złe i kompilatory ostrzegają, że taka konwersja została użyta.

@temat: Z tych najlepsza jest nazwa4() - zwraca wskaźnik na stałą (bo i po co zmieniać literał napisowy?) i jednocześnie można wywołać ją na stałym obiekcie - i racja, w końcu jakby nie patrzeć to ta metoda nie zmienia obiektu.

0

dzięki :) czyli const za nazwą funkcji mówi tylko o tym że ta funkcja nie zmienia nic w obiekcie?

użycie const char* oznacza że wskaźnik jest stały czy, że pamięć (napis) pod tym adresem jest nie do zmiany? czy jedno i drugie?

0
krwq napisał(a)

czyli const za nazwą funkcji mówi tylko o tym że ta funkcja nie zmienia nic w obiekcie?
Tak, i z tego powodu można ją wywołać na stałych obiektach klasy.

krwq napisał(a)

użycie const char* oznacza że wskaźnik jest stały czy, że pamięć (napis) pod tym adresem jest nie do zmiany? czy jedno i drugie?
Napis pod tym wskaźnikiem jest stały. Stały wskaźnik to "char* const".

0

czyli stały wskaźnik do stałego napisu to byłoby: const char* const? :P

0
krwq napisał(a)

czyli stały wskaźnik do stałego napisu to byłoby: const char* const? :P

Dokladnie tak!
Pierwszy const oznacza ze nie wolno modyfikowac stringa a drugi oznacza ze nie mozesz zmieniac adresu
zawartego we wskazniku. Mam tu odpowiedni przyklad w ANSI C:

#include <string.h>

int main()
{
  const char const n[20] = "constpointer";
  char tab[] = "xmoon";
  n = tab; // const pointer is read-only!
  n[2] = 'x'; // const varible is read-only!
}

Powyzszy kod sie oczywiscie nie skompiluje, ale pokaze co sie dzieje przy modyfikacji stalego wskaznika.

pozdro.

0

Hm, ale gdzie w tym kodzie jest jakikolwiek wskaźnik?

0

Nazwa tablicy jest wskaznikiem :-)

0
xmoon napisał(a)

Nazwa tablicy jest wskaznikiem :-)
Tak, możliwe, ale nie w C++ (o którym jest ten temat)...

ISO/IEC 14882:2003, 4.2.1 napisał(a)

An lvalue or rvalue of type “array of N T” or “array of unknown bound of T” can be converted to an rvalue of type “pointer to T.” The result is a pointer to the first element of the array.
Nie kłóć się ze standardem, to on określa język, nie ty...

0

Tablica i wskaźnik są traktowane jednakowo w C++, więc o co tutaj się spierać?

Co do pytania to ja bym zastosował funkcję nr. 4.
const char* - napis tylko w celach informacyjnych, nie można sobie go od tak zmienić :)
const na końcu deklaracji - jak metoda dostępowa, nie zmieniająca nic w ciele to dlaczego miałaby być nie dostępna dla stałych obiektów

0

@tobix10 bzdura. Mozesz uzywać tablicy jako wskaźnika, bo zajdzie konwersja, ale w drugą stronę już nie.
Dowód na to ze jednak nie jest to to samo? sizeof()

1 użytkowników online, w tym zalogowanych: 0, gości: 1