Чего вам не хватает, так это списка инициализаторов.
Type::Type(Parameters)
: member1(init) // This is the initializer list
, member2(init)
{
Your code
}
Если вы явно не предоставите его, компилятор сделает это за вас, используя конструктор по умолчанию для родительского класса, а затем вызов конструктора по умолчанию для каждого члена.
Итак, давайте посмотрим на ваш класс.
Student::Student(const std::string & name, int age, const std::string & course)
{
// Code
}
Это то, что вы написали. Но это то, что реализовал компилятор.
Student::Student(const std::string & name, int age, const std::string & course)
: Person()
, course()
{
// Code
}
Так как вы ничего не сделали, компилятор добавил, что он вызывает конструктор по умолчанию Person
и конструктор по умолчанию course (std::string)
.
Теперь проблема возникает, если ваш базовый класс не имеет конструктора по умолчанию. Тогда компилятор не сможет добавить соответствующие вызовы и сгенерирует ошибку компилятора.
Но есть и проблема в том, что то, как вы пишете, очень неэффективно, поскольку вы в основном инициализируете всех членов дважды. Вы вызываете конструктор по умолчанию, а затем в разделе Code вы повторно инициализируете элементы с другим значением.
Student::Student(const std::string & name, int age, const std::string & course)
: Person(name, age)
, course() // Initialize it to empty here.
{
course = "[unassigned course]"; // Re-Initialize it with info.
}
Вы можете просто сделать это один раз:
Student::Student()
: Person() // Note person must have a default constructor for this to work.
, course("[unassigned course]")
{}
Student::Student(const std::string & name, int age, const std::string & course)
{
Person(name, age);
// CODE.
}
Это не то, что вы думаете.
Добавим список инициализаторов.
Student::Student(const std::string & name, int age, const std::string & course)
: Person()
, course()
{
Person(name, age); // This is creating a person object localy.
// the person object has no name so is a
// temporary variable and goes out of scope
// at the ';'. So it is created and destroyed
// in place before other code is executed.
//
// This does not help initialize the class.
// It is creating a completely different
// and independent object.
// CODE.
}
Вы можете увидеть выполнение здесь:
Hello from Person::Person() // Init parent
Hello from Person::Person(string, int) // Init the temp object.
// If you put a print in the destructor
// You will also see that executed
// Before the Student
// This is also why the object has "unknown name" and 0 age.
Hello from Student::Student(string, int, string) // Now we init the student
[unknown name], 0
Physics
Есть ли допустимый сценарий, в котором вы хотите инициализированные версии объекта? Лично я думаю, что нет (если есть тогда игнорировать это), поэтому избавиться от конструкторов по умолчанию Person
и Student
. Тогда вы не можете создавать неинициализированные Students
или `People.
Почему бы не позволить пользователю обновлять их оценку? Возможно, их первая оценка была поспешной, и они хотели бы изменить ее или могут быть, они просто нажали неправильную звезду.
Конечно, Вам был бы нужен некоторый способ идентифицировать каждого пользователя и где-нибудь сохранить каждую пользовательскую оценку каждого объекта.
(Я на самом деле не знаю, как сделать любое из этого, но с точки зрения удобства использования, это кажется лучшим подходом, чем удостоверяются, что Вы получаете его в правильный первый раз, потому что Вы не можете изменить его впоследствии.)
Это может быть подобно Вашей 'перезагрузке отделение' решение, но я думаю, что лучшее решение может быть для простого отключения входных параметров после выполнения запроса Ajax. При использовании jQuery.ajax, можно указать, что функция обратного вызова для погони за запросом завершается.
jQuery.ajax({
type: "POST",
url: ...
data: ...
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(msg) {
jQuery('.star').attr('disabled', true);
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
displayError();
}
});
С их веб-сайта:
Используйте отключенное свойство для использования управления в целях дисплея только
<input name="star3" type="radio" class="star" disabled="disabled"/>
<input name="star3" type="radio" class="star" disabled="disabled"/>
<input name="star3" type="radio" class="star" disabled="disabled" checked="checked"/>
<input name="star3" type="radio" class="star" disabled="disabled"/>
<input name="star3" type="radio" class="star" disabled="disabled"/>
Проблема была решена в последнем выпуске плагина. Теперь на обратном вызове можно просто сделать:
this.rating('disable');
Yey!
Я - автор плагина, и я имею просто (буквально просто), выпустил новую версию (3.1), которая должна заботиться о вопросах, которые Вы обсуждали здесь.
planetjones, обратите внимание, что this.rating ('отключают'); не то же как this.rating ('только для чтения'); this.rating ('только для чтения'), будет мешать управлению изменить текущий выбор, тогда как this.rating ('отключают'), будет препятствовать тому, чтобы значение было отправлено в целом.
svinto, плагин, используемый для удаления радио-полей но теперь, это скрывает их. для возвращения, все, что необходимо сделать, 1. удалите звезды 2. покажите радио-поля 3. удалите данные плагина из радио-полей - $ () .data ('оценка') и $ () .data ('rating.star') 4. развяжите событие 'изменения' от радио-полей
Между прочим, об обновлениях объявят здесь: http://twitter.com/fyneworks
То, что Вы действительно хотели бы, должно вернуться элементы к переключателям, затем добавив только для чтения и затем заставив их выглядеть хорошим снова. Возвращение, кажется, не возможно, но Вы могли развязать все события на сообщении к серверу. $ ("... ") .unbind ();