Проблема с аргументом указателя char в конструкторе (C ++) - PullRequest
0 голосов
/ 17 июня 2020

Я начал изучать C ++ по книге какое-то время go, и теперь я застрял с частью кода из книги, которая не работает в моем API, то есть Visual Studio 2019. Книга датируется 2000 годом. , так что это может быть частью проблемы, но если это так, не могли бы вы сказать мне, как исправить это?

Проблема в следующем коде. Автор книги хочет использовать массив символов в качестве аргумента для конструктора и делает это с помощью указателя (char * pName). Однако Visual Studio подчеркивает аргумент («0. DannyBoy»). Я огляделся в поисках ответов, но ни один из них не похож на мой. Был бы очень признателен, если бы мне кто-нибудь помог!

#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <string.h>
using namespace std;

const int MAXNAMESIZE = 40;

class Student
{
public:
    Student(char* pName)
    {
        strncpy_s(name, pName, MAXNAMESIZE);
        name[MAXNAMESIZE - 1] = '\0';
        semesterHours = 0;
        gpa = 0;
    }

    //... autres membres publics...
protected:
    char name[MAXNAMESIZE];
    int semesterHours;
    float gpa;
};

int main(int argcs, char* pArgs[])
{
    Student s("0. DannyBoy");
    Student* pS = new Student("E. Z. Rider");

    system("pause");
    return 0;
}

Ответы [ 3 ]

1 голос
/ 17 июня 2020

Строковые литералы имеют тип const char [], который распадается на const char *. Ваш конструктор должен иметь const char *:

//      VVVVV
Student(const char* pName)
{
    strncpy_s(name, pName, MAXNAMESIZE);
    name[MAXNAMESIZE - 1] = '\0';
    semesterHours = 0;
    gpa = 0;
}
0 голосов
/ 17 июня 2020

В C исторически строковые литералы имеют типы непостоянных массивов символов. И до C ++ 11 Standard компиляторы C ++ позволяли использовать строковые литералы в качестве аргументов параметров непостоянного типа char * для обратной совместимости.

Однако, хотя в C строковые литералы имеют непостоянные массивы символов, тем не менее вы не может их изменять.

В C ++ 11 было решено не разрешать использование строковых литералов с типом char *, потому что в C ++ они имеют типы постоянных массивов символов.

Итак, объявите конструктор, например

Student( const char *pName )

В любом случае это лучше, потому что это объявление говорит читателю класса, что переданная строка не будет изменена в конструкторе, даже если аргумент не будет строковым литералом.

0 голосов
/ 17 июня 2020

В этой строке:

Student s("0. DannyBoy");

вы передаете строковый литерал типа char[12] конструктору Student.

Однако вам нужно использовать char const * для привязки к массиву char, поэтому ваш конструктор должен выглядеть так:

Student(char const * pName) {
...