Почему головка таблицы игнорирует элемент: before? [Дубликат]

Когда объекту класса Derived присвоен объект Base class Object, все члены объекта производного класса копируются в объект базового класса, за исключением членов, которых нет в базовом классе. Эти члены удаляются компилятором. Это называется Object Slicing.

Вот пример:

#include<bits/stdc++.h>
using namespace std;
class Base
{
    public:
        int a;
        int b;
        int c;
        Base()
        {
            a=10;
            b=20;
            c=30;
        }
};
class Derived : public Base
{
    public:
        int d;
        int e;
        Derived()
        {
            d=40;
            e=50;
        }
};
int main()
{
    Derived d;
    cout<<d.a<<"\n";
    cout<<d.b<<"\n";
    cout<<d.c<<"\n";
    cout<<d.d<<"\n";
    cout<<d.e<<"\n";


    Base b = d;
    cout<<b.a<<"\n";
    cout<<b.b<<"\n";
    cout<<b.c<<"\n";
    cout<<b.d<<"\n";
    cout<<b.e<<"\n";
    return 0;
}

Он будет генерировать:

[Error] 'class Base' has no member named 'd'
[Error] 'class Base' has no member named 'e'
0
задан Ian Schorr 3 September 2013 в 23:00
поделиться

2 ответа

Это происходит потому, что таблица не может семантически содержать внутри него элемент уровня блока. Использование псевдоэлементов :before и :after добавляет это содержимое до и после содержимого внутри этого родителя. Чтобы перевести это в более понятный аспект, вот что ваш окончательный результат будет технически выглядят в конце:

<table class="minTable" width="800" border="0" cellpadding="0" cellspacing="0">
  <div class="before">
    <img src="topleft.png" />
  </div>
  <tr>
    <td>Some text</td>
    <td>Some other text</td>
  </tr>
  <div class="after">
    <img src="topleft.png" />
  </div>
</table>

Конечно, .before и .after наследуют их уважающие стили, связанные с псевдоэлементом. Однако вы можете себе представить, что элемент уровня блока внутри такой таблицы не будет действовать должным образом, потому что элементы уровня блока не принадлежат внутри таблицы.

Как правило, Я бы даже пытался использовать :before и :after с таблицами - это просто просит беспорядок.


Если вы просто пытаетесь добавить углы, я бы использовал CSS для выбора каждой угловой ячейки. Что-то вроде этого:

.minTable > :first-child > tr:first-child > td:first-child /* Top-left corner */
.minTable > :first-child > tr:first-child > td:last-child /* Top-right corner */
.minTable > :last-child > tr:last-child > td:first-child /* Bottom-left corner */
.minTable > :last-child > tr:last-child > td:last-child /* Bottom-right corner */

Эти селекторы не будут работать, если: a) у вас нет элементов вашего тела таблицы вне порядка (например, thead, then tfoot, then tbody - он будет выбирать элементы в tbody для углы, даже если tfoot появится ниже); б) у вас есть элемент colgroup в начале вашей таблицы; или c) вы используете rowspans, которые заставляют нижние ячейки фактически быть частью ячеек в строке выше.

2
ответ дан animuson 21 August 2018 в 09:22
поделиться
  • 1
    Ага, это имеет смысл. Я думал, что было больше волшебства, чем есть, но это очень ясно. Спасибо за подсказку по другому методу. Мне нужно делать другие вещи, кроме добавления углов, но углы действительно являются моей главной задачей. – Ian Schorr 3 September 2013 в 23:28
  • 2
    – Ilya Streltsyn 29 October 2018 в 20:07

Псевдоэлементы :before и :after отображаются внутри элемента, который они изменяют. Это означает, что если вы примените их к таблице, браузер попытается отобразить ее display: block в таблице, где она не принадлежит. Я подозреваю, что неправильная ширина - это просто артефакт конкретного браузера, который вы используете, пытаясь сделать что-то, что он не должен делать вообще. [Edit: Alohci предоставил объяснение, что браузер молча загружает содержимое :after в table-cell, завернутое в table-row. Это приведет к тому, что содержимое станет шириной одного столбца.]

Возможно, ваш код будет работать так, как ожидалось, если вы примените его к <div>, обернув <table>? Добавление <div> таким образом обычно является хорошей идеей только для того, чтобы получить достаточный контроль над компоновкой таблицы.

1
ответ дан meustrus 21 August 2018 в 09:22
поделиться
  • 1
    Благодарю. Думаю, это имеет смысл. Я предполагал, что с точки зрения того, как они будут интерпретироваться для каждого элемента, к которому они применяются, должны быть некоторые умственные способности (поэтому были бы четкие правила о том, как: раньше применимо к & lt; table & gt;), но в этом случае это не определено? Обертка таблицы в & lt; div & gt; будет моим обходным путем, но я надеялся избежать этого. Цель здесь заключалась в том, чтобы попытаться определить как можно больше стиля таблицы в классе CSS. Старался максимально абстрагироваться. – Ian Schorr 3 September 2013 в 23:18
  • 2
    Я оставил бы это кому-то, лучше понимая спецификацию CSS, чтобы сказать, не определено ли table:before. Во всяком случае, отсутствие не смысловой разметки - это мечта, которая еще не реализована даже с последними прохладными стандартами. – meustrus 3 September 2013 в 23:32
  • 3
    Я начал спрашивать вас, будет ли мой пример похожим на то, что вы получите, если я вставил теги и другое содержимое между & lt; table & gt; и & lt; tr & gt ;, но похоже, что это именно то, что я делал =) – Ian Schorr 3 September 2013 в 23:41
  • 4
    @IanSchorr - я не думаю, что таблица: перед отображением: блок не определен, хотя насколько хорошо он реализован - это другое дело. Что должно произойти, так это то, что псевдоэлементы будут обернуты в анонимные объекты таблицы , поэтому каждый псевдоэлемент окажется в таблице-строке, содержащей одну таблицу-ячейку, каждая из которых, очевидно, будет отображается в первом столбце таблицы. Это согласуется с поведением, которое вы описываете в своем вопросе. – Alohci 4 September 2013 в 00:37