Операторы преобразования в C++

Вы могли использовать обертку вокруг исходного массива (который является IList), как в этой (непротестированной) части кода.

public class SubList<T> : IList<T>
{
    #region Fields

private readonly int startIndex;
private readonly int endIndex;
private readonly int count;
private readonly IList<T> source;

#endregion

public SubList(IList<T> source, int startIndex, int count)
{
    this.source = source;
    this.startIndex = startIndex;
    this.count = count;
    this.endIndex = this.startIndex + this.count - 1;
}

#region IList<T> Members

public int IndexOf(T item)
{
    if (item != null)
    {
        for (int i = this.startIndex; i <= this.endIndex; i++)
        {
            if (item.Equals(this.source[i]))
                return i;
        }
    }
    else
    {
        for (int i = this.startIndex; i <= this.endIndex; i++)
        {
            if (this.source[i] == null)
                return i;
        }
    }
    return -1;
}

public void Insert(int index, T item)
{
    throw new NotSupportedException();
}

public void RemoveAt(int index)
{
    throw new NotSupportedException();
}

public T this[int index]
{
    get
    {
        if (index >= 0 && index < this.count)
            return this.source[index + this.startIndex];
        else
            throw new IndexOutOfRangeException("index");
    }
    set
    {
        if (index >= 0 && index < this.count)
            this.source[index + this.startIndex] = value;
        else
            throw new IndexOutOfRangeException("index");
    }
}

#endregion

#region ICollection<T> Members

public void Add(T item)
{
    throw new NotSupportedException();
}

public void Clear()
{
    throw new NotSupportedException();
}

public bool Contains(T item)
{
    return this.IndexOf(item) >= 0;
}

public void CopyTo(T[] array, int arrayIndex)
{
    for (int i=0; i<this.count; i++)
    {
        array[arrayIndex + i] = this.source[i + this.startIndex];
    }
}

public int Count
{
    get { return this.count; }
}

public bool IsReadOnly
{
    get { return true; }
}

public bool Remove(T item)
{
    throw new NotSupportedException();
}

#endregion

#region IEnumerable<T> Members

public IEnumerator<T> GetEnumerator()
{
    for (int i = this.startIndex; i < this.endIndex; i++)
    {
        yield return this.source[i];
    }
}

#endregion

#region IEnumerable Members

IEnumerator IEnumerable.GetEnumerator()
{
    return GetEnumerator();
}

#endregion

}

28
задан Ravid Goldenberg 20 June 2013 в 17:56
поделиться

3 ответа

Example exObject = theInt; // implicitly created copy constructor takes place
// object implicitly created from int and then copied
// it is like
Example exObject = Example(theInt);
// so it uses sequence
// Example(int) -> Example(const Example&)
int theInt1 = ctr; // operator int()

Если ваш компилятор поддерживает оптимизацию конструктора копирования и оптимизацию возвращаемого значения, вы не заметите выполнения

Example(const Example&)

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

4
ответ дан 28 November 2019 в 03:53
поделиться

Вы можете пройтись по этому коду с помощью отладчика (и / или поставить точку останова на каждый из ваших конструкторов и операторов), чтобы увидеть, какие из ваших конструкторов и операторов вызываются какими строками.

Поскольку вы не определили их явно, компилятор также создал скрытый / стандартный конструктор копирования и оператор присваивания для вашего класса. Вы можете определить их явно (как показано ниже), если хотите использовать отладчик, чтобы увидеть, где и когда они вызываются.

Example::Example(const Example& rhs)
: itsVal(rhs.itsVal)
{}

Example& operator=(const Example& rhs)
{
    if (this != &rhs)
    {
        this->itsVal = rhs.itsVal;
    }
    return *this;
}
9
ответ дан 28 November 2019 в 03:53
поделиться

Я бы попробовал это на Linux или BSD, просто чтобы посмотреть, как это работает, из любопытства.

У меня очень приблизительное предположение о проблеме: Бьюсь об заклад, что Windows выполняет множество дополнительных проверок, чтобы убедиться, что не отображается конец файла. В прошлом в некоторых ОС возникали проблемы с безопасностью, которые позволяли пользователю mmap просматривать личные данные файловой системы или данные из других файлов в области сразу за концом карты, поэтому осторожность здесь - хорошая идея для разработчика ОС. . Таким образом, Windows может использовать гораздо более осторожный метод «копирование данных с диска в ядро, обнуление несопоставленных данных, копирование данных для пользователя» вместо гораздо более быстрого «копирования данных с диска на пользователя».

Попробуйте сопоставить данные непосредственно под конец файла, за исключением последних байтов, которые не помещаются в блок размером 64 КБ.

осуществляется неявным конструктором, который принимает int.

Для этого также требуется наличие конструктора копирования для Example, даже если компилятору разрешено не копировать экземпляр.

int theInt1 = ctr; // here

Здесь используется неявное преобразование Example в unsigned int , предоставляемый оператором приведения.

Операторов приведения обычно избегают, поскольку они имеют тенденцию приводить к путанице в коде, и вы можете явно пометить конструкторы с одним аргументом, чтобы отключить неявные преобразования в тип вашего класса. В C ++ 0x также должна быть добавлена ​​возможность явно отмечать операторы преобразования (так что вам понадобится static_cast для их вызова? - мой компилятор не поддерживает их, и все веб-ресурсы, похоже, сосредоточены на явном преобразовании в bool).

даже если компилятору разрешено опускать копирование экземпляра.

int theInt1 = ctr; // here

Здесь используется неявное преобразование Example в unsigned int, предоставляемое оператором приведения.

Операторов приведения обычно избегают, поскольку они имеют тенденцию приводить к запутанному коду и вы можете пометить конструкторы с одним аргументом явно, чтобы отключить неявные преобразования в тип вашего класса. C ++ 0x также должен добавить возможность явно отмечать операторы преобразования (так что вам понадобится static_cast для их вызова? - мой компилятор не поддерживает их, и все веб-ресурсы, похоже, сосредоточены на явном преобразовании в bool).

даже если компилятору разрешено опускать копирование экземпляра.

int theInt1 = ctr; // here

Здесь используется неявное преобразование Example в unsigned int, предоставляемое оператором приведения.

Операторов приведения обычно избегают, поскольку они имеют тенденцию приводить к запутанному коду и вы можете пометить конструкторы с одним аргументом явно, чтобы отключить неявные преобразования в тип вашего класса. C ++ 0x также должен добавить возможность явно отмечать операторы преобразования (так что вам понадобится static_cast для их вызова? - мой компилятор не поддерживает их, и все веб-ресурсы, похоже, сосредоточены на явном преобразовании в bool).

и вы можете пометить конструкторы с одним аргументом явным образом, чтобы отключить неявные преобразования в ваш тип класса. C ++ 0x также должен добавить возможность явно отмечать операторы преобразования (так что вам понадобится static_cast для их вызова? - мой компилятор не поддерживает их, и все веб-ресурсы, похоже, сосредоточены на явном преобразовании в bool).

и вы можете пометить конструкторы с одним аргументом явным образом, чтобы отключить неявные преобразования в ваш тип класса. C ++ 0x также должен добавить возможность явно отмечать операторы преобразования (так что вам понадобится static_cast для их вызова? - мой компилятор не поддерживает их, и все веб-ресурсы, похоже, сосредоточены на явном преобразовании в bool).

2
ответ дан 28 November 2019 в 03:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: