Просто переопределяют поля first_name и last_name , как показано ниже, и делают их пустыми = True, пустыми = True
CustomUser(AbstractUser):
first_name= models.CharField(null=True, blank=True, max_length=100)
last_name = models.CharField(null=True, blank=True, max_length=100)
.........
.........
Явно определенные конструкторы копирования не вызывают конструкторы копирования для членов.
При вводе тела конструктор, каждый член этого класса будет инициализирован. То есть, как только вы доберетесь до {
, вам гарантируется, что все ваши члены были инициализированы.
Если не указано, члены инициализируются по умолчанию в порядке их появления в классе. (И если они не могут быть, программа плохо сформирована.) Так что, если вы определяете свой собственный конструктор копирования, теперь вы можете вызывать любые конструкторы копирования членов по желанию.
Вот небольшая программа, которую вы можете скопируйте-вставьте куда-нибудь и возитесь с:
#include <iostream>
class Foo {
public:
Foo() {
std::cout << "In Foo::Foo()" << std::endl;
}
Foo(const Foo& rhs) {
std::cout << "In Foo::Foo(const Foo&)" << std::endl;
}
};
class Bar {
public:
Bar() {
std::cout << "In Bar::Bar()" << std::endl;
}
Bar(const Bar& rhs) {
std::cout << "In Bar::Bar(const Bar&)" << std::endl;
}
};
class Baz {
public:
Foo foo;
Bar bar;
Baz() {
std::cout << "In Baz::Baz()" << std::endl;
}
Baz(const Baz& rhs) {
std::cout << "In Baz::Baz(const Baz&)" << std::endl;
}
};
int main() {
Baz baz1;
std::cout << "Copying..." << std::endl;
Baz baz2(baz1);
}
Как есть, это печатает:
In Foo::Foo() In Bar::Bar() In Baz::Baz() Copying... In Foo::Foo() In Bar::Bar() In Baz::Baz(const Baz&)
Обратите внимание, что по умолчанию инициализируются члены Baz
.
Закомментировав явный конструктор копирования, подобно:
/*
Baz(const Baz& rhs) {
std::cout << "In Baz::Baz(const Baz&)" << std::endl;
}
*/
Вывод будет следующим:
In Foo::Foo() In Bar::Bar() In Baz::Baz() Copying... In Foo::Foo(const Foo&) In Bar::Bar(const Bar&)
Он вызывает конструктор копирования в обоих случаях.
И если мы вновь введем конструктор копирования [Baz
и явно скопируем один элемент:
Baz(const Baz& rhs) :
foo(rhs.foo)
{
std::cout << "In Baz::Baz(const Baz&)" << std::endl;
}
Мы get:
In Foo::Foo() In Bar::Bar() In Baz::Baz() Copying... In Foo::Foo(const Foo&) In Bar::Bar() In Baz::Baz(const Baz&)
Как видите, как только вы явно объявите конструктор копирования , вы отвечаете за копирование всех членов класса; теперь это ваш конструктор.
Это относится ко всем конструкторам, включая конструкторы перемещения.
Для любой переменной-члена, имеющей конструктор по умолчанию, этот конструктор по умолчанию вызывается, если вы явно не добавили какой-либо другой вызов конструктора для этой переменной-члена в список инициализации.
For details see: Is there an implicit default constructor in C++?
Short:
There is nothing magical about a copy constructor, other than that the compiler will add it in if needed. But in how it actually runs, there is nothing special - if you don't explicitly say "use such and such a constructor", it'll use the default.
Not in VC9. Not sure about the others.
// compiled as: cl /EHsc contest.cpp
//
// Output was:
// Child1()
// -----
// Child1()
// Child2()
// Parent()
// -----
// Child1(Child1&)
// Child2()
// Parent(Parent&)
#include <cstdio>
class Child1 {
int x;
public:
static Child1 DEFAULT;
Child1(){
x = 0;
printf("Child1()\n");
}
Child1(Child1 &other){
x = other.x;
printf("Child1(Child1&)\n");
}
};
Child1 Child1::DEFAULT;
class Child2 {
int x;
public:
Child2(){
x = 0;
printf("Child2()\n");
}
Child2(Child2 &other){
x = other.x;
printf("Child2(Child2&)\n");
}
};
class Parent {
int x;
Child1 c1;
Child2 c2;
public:
Parent(){
printf("Parent()\n");
}
Parent(Parent &other) : c1(Child1::DEFAULT) {
printf("Parent(Parent&)\n");
}
};
int main(){
printf("-----\n");
Parent p1;
printf("-----\n");
Parent p2(p1);
return 0;
}
Когда компилятор предоставляет cctor по умолчанию, что, по вашему мнению, компилятор делает для переменных-членов? Он копирует, создает it.
В том же духе, если cctor определен пользователем и если пропущено несколько членов, эти члены нельзя оставлять неинициализированными. Инварианты класса устанавливаются во время строительства и должны постоянно поддерживаться. Итак, компилятор сделает это за вас.