Podana klasa z polem const char* filename;, dzięki czemu nazwa klasy jest na przykład myClass.

#include <cstring>
class MyClass{
const char* filename;
public:
       MyClass(const char* name);
};

Jak mogę zainicjować pole filename przez name?
Uwaga: Muszę to zrobić z funkcją strcpy.
Czy istnieje sposób na to z listą inicjalizacji?

1
AskMath 4 czerwiec 2018, 12:30

3 odpowiedzi

Najlepsza odpowiedź

Czy istnieje sposób na to z listą inicjalizacji?

Istniejemy, musisz użyć strdup Funkcja:

class MyClass {
    const char* filename;
public:
    MyClass(const char* name)
        : filename(strdup(name))
    {
        if(!filename)
            throw std::bad_alloc(); // strdup failed.
    }

    ~MyClass() {
        free(const_cast<char*>(filename));
    }

    MyClass(MyClass const&) = delete;
    MyClass& operator=(MyClass const& b) = delete;
};
4
Maxim Egorushkin 4 czerwiec 2018, 10:03
MyClass::MyClass(char const* filename)
    : filename(strcpy(new char[strlen(filename) + 1], filename))
    //                                          ^^^ space for trailing 0!
{ }

Jak przy użyciu nowego, w przypadku awarii alokacji zostanie rzuconych STD :: Bad_alloc, a StrCpy nigdy nie zostanie nazwany, więc jesteśmy w porządku.

Nie zapomnij delete[] filename; w destructor (nie {x1}}, nie byłeś malloc!), W przeciwnym razie masz wyciek pamięci.

edytuj (kradzież pomysłów z komentarzy Maxima ...):

Korzystając z Lambda, możesz czerpać korzyści z bardziej wydajnego MEMCPY:

MyClass::MyClass(char const* filename)
    : filename([](char const* value)
      {
          size_t len = strlen(filename) + 1;
          return reinterpret_cast<char*>(memcpy(new char[len], value, len));
      }())
{ }

Otrzymasz jednak wszystkie problemy za darmo, jeśli zamiast tego przełączysz na std::string:

MyClass
{
    std::string filename;
public:
    MyClass(char const* filename) : filename(filename) { }
};

Nie potrzebujesz nawet wyraźnego destruktora (pod warunkiem, że nie ma nic innego do sprzątania ...) - Użyj filename.c_str() w char const* Getter, w razie potrzeby.

1
Deduplicator 4 czerwiec 2018, 11:58

Praca z char* jest bardzo trudna. Polecam użyć ciągów do przechowywania {x1}}. Ale nadal chcesz użyć char*. Możesz spróbować w następujący sposób:

MyClass(const char* name)
{
  filename = new char[100];
  for(int i=0;name[i]!='\0';i++) 
  {
     filename[i]=name[i];
  }
}
0
Ta Quang Tu 4 czerwiec 2018, 09:54