Динамическое связывание использует vpointer и vtable. Однако динамическое связывание применяется только к указателю на функцию. Механизм динамического связывания отсутствует.
Таким образом, аргумент по умолчанию определяется статически во время компилятора. В этом случае он статически определяется типом bp, который является указателем на базовый класс. Таким образом, data = 10 передается как аргумент функции, а указатель функции указывает на функцию класса Derived: D :: print. По сути, он вызывает D :: print (10).
Следующий фрагмент кода и результирующие выходы четко демонстрируют точку: даже если он вызывает функцию Derived call member Derived :: resize (int), это передает основной аргумент по умолчанию: size = 0.
virtual void Derived :: resize (int) size 0
#include <iostream>
#include <stdio.h>
using namespace std;
#define pr_dbgc(fmt,args...) \
printf("%d %s " fmt "\n",__LINE__,__PRETTY_FUNCTION__, ##args);
class Base {
public:
virtual void resize(int size=0){
pr_dbgc("size %d",size);
}
};
class Derived : public Base {
public:
void resize(int size=3){
pr_dbgc("size %d",size);
}
};
int main()
{
Base * base_p = new Base;
Derived * derived_p = new Derived;
base_p->resize(); /* calling base member function
resize with default
argument value --- size 0 */
derived_p->resize(); /* calling derived member
function resize with default
argument default --- size 3 */
base_p = derived_p; /* dynamic binding using vpointer
and vtable */
/* however, this dynamic binding only
applied to function pointer.
There is no mechanism to dynamic
binding argument. */
/* So, the default argument is determined
statically by base_p type,
which is pointer to base class. Thus
size = 0 is passed as function
argument */
base_p->resize(); /* polymorphism: calling derived class
member function
however with base member function
default value 0 --- size 0 */
return 0;
}
#if 0
The following shows the outputs:
17 virtual void Base::resize(int) size 0
24 virtual void Derived::resize(int) size 3
24 virtual void Derived::resize(int) size 0
#endif
SQL Server 2005 вперед:
IF EXISTS(SELECT 1 FROM sys.columns
WHERE Name = N'columnName'
AND Object_ID = Object_ID(N'schemaName.tableName'))
BEGIN
-- Column Exists
END
версия Martin Smith короче:
IF COL_LENGTH('schemaName.tableName', 'columnName') IS NOT NULL
BEGIN
-- Column Exists
END
Попробуйте это...
IF NOT EXISTS(
SELECT TOP 1 1
FROM INFORMATION_SCHEMA.COLUMNS
WHERE
[TABLE_NAME] = 'Employees'
AND [COLUMN_NAME] = 'EmployeeID')
BEGIN
ALTER TABLE [Employees]
ADD [EmployeeID] INT NULL
END
Настройте ниже для удовлетворения конкретным требованиям:
if not exists (select
column_name
from
INFORMATION_SCHEMA.columns
where
table_name = 'MyTable'
and column_name = 'MyColumn')
alter table MyTable add MyColumn int
Редактирование для контакта с редактированием к вопросу : Это должно работать - бросают осторожный взгляд по Вашему коду для глупых ошибок; Вы запрашиваете INFORMATION_SCHEMA на той же базе данных, как к Вашей вставке относятся, например? У Вас есть опечатка в Вашей таблице/имени столбца в любом операторе?
Сначала проверьте, существует ли table
/ column
(id
/ name
) комбинация в dbo.syscolumns
(внутренняя таблица SQL Server, которая содержит определения поля), и если не выпускают соответствующее ALTER TABLE
запрос для добавления его. Например:
IF NOT EXISTS ( SELECT *
FROM syscolumns
WHERE id = OBJECT_ID('Client')
AND name = 'Name' )
ALTER TABLE Client
ADD Name VARCHAR(64) NULL
Попробуйте что-то как:
CREATE FUNCTION ColumnExists(@TableName varchar(100), @ColumnName varchar(100))
RETURNS varchar(1) AS
BEGIN
DECLARE @Result varchar(1);
IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.Columns WHERE TABLE_NAME = @TableName AND COLUMN_NAME = @ColumnName)
BEGIN
SET @Result = 'T'
END
ELSE
BEGIN
SET @Result = 'F'
END
RETURN @Result;
END
GO
GRANT EXECUTE ON [ColumnExists] TO [whoever]
GO
Тогда использование это как это:
IF ColumnExists('xxx', 'yyyy') = 'F'
BEGIN
ALTER TABLE xxx
ADD yyyyy varChar(10) NOT NULL
END
GO
Это должно работать над обоими SQL Server 2000 & SQL Server 2005. Не уверенный в SQL Server 2008, но не смотрите почему нет.
Можно использовать системные представления информационной схемы для обнаружения в значительной степени чего-либо о таблицах, которыми Вы интересуетесь:
SELECT *
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'yourTableName'
ORDER BY ORDINAL_POSITION
можно также опросить представления, хранимые процедуры и в значительной степени что-либо о базе данных с помощью представлений Information_schema.
Делают что-то, если столбец не является существующим:
BEGIN
IF (COL_LENGTH('[dbo].[Table]', 'Column ') IS NULL)
BEGIN
//Do something
END
END;
Делают что-то, если столбец является существующим:
BEGIN
IF (COL_LENGTH('[dbo].[Table]', 'Column ') IS NOT NULL)
BEGIN
//Do something
END
END;
I'd prefer INFORMATION_SCHEMA.COLUMNS
over a system table because Microsoft does not guarantee to preserve the system tables between versions. For example, dbo.syscolumns
does still work in SQL 2008, but it's deprecated and could be removed at any time in future.