Ваш дизайн разумен и следует за корректными правилами нормализации. Вы могли бы пропускать таблицу Vehicle с идентификатором Механизма и Типом (т.е. "родитель" для Быстроходных катеров, Автомобилей и Gokarts..., где Вы сохраните материал как "DesignedByUserId"). Между таблицей Vehicle и Speedboats таблица - одна - к - отношения, и между Механизмом и Speedboat/Cars/GoKarts, там 1-and-only-1 отношения (т.е. механизм может только иметь 1 запись для быстроходного катера, автомобилей или пойти карты)..., хотя большая часть дб не предлагает легкий механизм осуществления для этого.
Одно правило нормализации, которое помогает определить эти виды вещей, - то, что поле должно зависеть только от первичного ключа таблицы. В объединенной таблице, где быстроходный катер, автомобили и gokart результаты испытаний хранятся вместе затем, автомобильные смежные области зависят не только от тестовой даты, но также и от vechicle идентификатора и типа механизма. Первичный ключ для таблицы результатов испытаний является тестовой датой + идентификатор механизма, и тип механизма не то, что делает строку данных тестирования уникальной (т.е. должен там так или иначе провести тест на 01/01/200912:30pm на одном определенном механизме, который является и быстроходным катером и автомобилем... нет... не может быть сделан).
я не объясняю, что правило нормализации particularily хорошо..., но 3-и/4-е/5-е правила нормальных форм всегда смущает меня, когда я прочитал формальные описания. Одно из тех (3-х/4-х/5-х) соглашений с полями в зависимости от первичного ключа и только первичного ключа. Правило делает предположение, что первичный ключ был правильно определен (неправильно defininh, первичный ключ слишком легко сделать).
Ключевое слово this
является указателем на текущий объект. Все нестатические функции-члены класса имеют доступ к указателю this.
Указатель на текущий объект обычно предоставляется компилятором в нестатической функции-члене с помощью регистра, обычно ECX. Поэтому, когда вы пишете this
в нестатической функции-члене, компилятор преобразует этот вызов в загрузку адреса из ECX.
Проверьте этот простой пример:
A t; t.Test(); 004114DE lea ecx,[t] 004114E1 call std::operator > (41125Dh)
Перед вызовом нестатической функции-члена Test ()
компилятор загружает регистр ECX с помощью [t] (адрес переменной t - будет this
внутри метода Test).
004114DE lea ecx,[t]
И внутри функции он может использовать ecx для получения адреса текущего экземпляра объекта.
Компилятор заботится о правильном разрешении этой ссылки во время компиляции. Если вы хотите узнать больше о некоторых методах, которые они используют для этого, эта книга расскажет вам все, что вам нужно знать:
http://en.wikipedia.org/wiki/Compilers:_Principles,_Techniques, _and_Tools
Хотя ответы, указывающие на то, что ссылка «this» по существу передается как волшебный «скрытый параметр» для вызова, по существу верны, полная история на самом деле немного сложнее в C #, чем может показаться на первый взгляд.
Типы ссылок просты; объект, на который указывает ссылка, проверяется на null и затем концептуально передается как безымянный, непеременный параметр с именем «this». История осложняется типами значений.
Помните, что типы значений по определению передаются по значению, то есть передаются путем создания копии данных. Отсюда и их название. Но явно изменяемые типы значений - которые являются чистым злом и которых следует избегать - не могут передаваться по значению как "this", потому что если вы вызвали мутатор, "this" в методе мутатора будет изменяться копия, а не оригинал!
Следовательно, в вызове метода типа значения «this» не является значением получателя, это псевдоним переменной, представляющей место хранения получателя . Мы реализуем это, передавая «this» в качестве управляемого адреса получателя, а не значения получателя.
Теперь мы можем поднять еще одну трудность. Что, если переменная, в которой хранится изменяемое значение, является переменной только для чтения ? Что нам теперь делать? Если вам интересно, прочтите мою статью на эту тему и посмотрите, сможете ли вы правильно ответить на поставленную задачу:
http://blogs.msdn.com/ericlippert/archive/2008/05/14/mutating-readonly- structs.aspx
Я бы ответил: «Кому какое дело? Он знает. Если мне когда-нибудь понадобится узнать подробности, я найду это в Google».
Вы, очевидно, знаете, что эффект от использования "this" будет, что, несомненно, является важным. Для 99% задач программирования я бы подумал, что детали того, как это решается внутри, - пустяки.
Оператор "this" будет указывать на текущий объект. Вот пример, в котором присутствие оператора this будет иметь значение:
public class MyClass
{
int value;
public void Test(int value)
{
MessageBox.Show(value); // Will show the parameter to the function
MessageBox.Show(this.value); // Will show the field in the object
}
}
Обратите внимание, что оператор this не изменит, какая виртуальная функция будет вызываться, если она переопределена в дочернем классе
public class MyClass
{
public virtual void Test() {}
public void CallTest()
{
this.Test();
}
}
public class MyClass2 : MyClass
{
public override void Test() {}
}
Если вы выполнение следующего кода
MyClass c = new MyClass2();
c.CallTest();
по-прежнему вызовет MyClass2.Test (), а не MyClass.Test ()
Таким образом, оператор «this» просто сообщает вам, что вы обращаетесь к чему-то объявленному на уровне класса.
this
является скрытым параметром во всех методах объекта и содержит копию указателя экземпляра.
Рассмотрим этот класс
class A {
private:
int data;
public:
void SetData(int arg) {
this->data = arg;
}
}
и этот код, который вызывает SetData ():
A objA;
objA.SetData(1);
Когда приведенный выше код компилируется, компилятор генерирует что-то эквивалентное этому для функции-члена:
void SetData(A* this, int arg) {
this->data = arg;
}
И вызывающий код преобразуется примерно в это:
A objA;
SetData(&objA, 1);
Это означает, что при компиляции:
Функции-члены преобразуются в простые глобальные функции.
Экземпляр класса, которому «принадлежат» функции-члены, просто передается им в качестве первого аргумента (или, скорее, передается его адрес).
Итак, в заключение, то, что вы называете этим указателем в вашем коде, просто заканчивается тем, что становится первым аргументом функции. Таким образом «система знает», к какому объекту нужно получить доступ через указатель «this».
Вышеупомянутый пример относится к C ++. Если вы на мгновение забудете про CLR, JITting и все такое,
Я бы ответил: «Это ссылка на экземпляр текущего класса».
Дэн
в c указатель this является аргументом невидимого указателя для вашего класса.
Таким образом, по сути, первый аргумент метода класса - это указатель на сам класс. Вы ссылаетесь на него, используя this.
Во время выполнения «this» преобразуется в указатель на текущий объект, поэтому «система» сможет вызвать соответствующий метод для этого объекта.
Компилятор схемы преобразует такой код:
pObject->someMethod(A,B,C)
В такой код, если someMethod не виртуальный:
someMethod(pObject,A,B,C)
Или в такой код, если someMethod виртуальный:
(*pObject->vtable[someMethodIndex]) (pObject, A,B,C)
И везде, где вы помещаете ключевое слово this, вместо него используется первый параметр;
Конечно, компилятор может оптимизировать / упростить, удалив первый аргумент и используя некоторый регистр ЦП (обычно esx) для хранения адреса объекта.